├── .gitignore ├── .vs └── RSP_TCP │ └── v15 │ └── .suo ├── LICENSE ├── README.md ├── RSP_TCP.sln ├── RSP_tcp_setup ├── Debug │ ├── sdr_tcp_setup.msi │ └── setup.exe ├── Release │ ├── RSP_tcp_setup.msi │ └── setup.exe └── sdr_tcp_setup.vdproj ├── Release ├── RSP_tcp.exe ├── mir_sdr_api.dll ├── msvcr100.dll ├── pthreadVC2.dll └── runme.bat ├── SDRplay_RSP_API_Release_Notes_V2.13.pdf ├── mirics_API ├── inc │ └── mir_sdr.h ├── x64 │ ├── mir_sdr_api.dll │ └── mir_sdr_api.lib └── x86 │ ├── mir_sdr_api.dll │ └── mir_sdr_api.lib ├── posix ├── dll │ ├── x64 │ │ ├── md5.sum │ │ ├── pthreadGC2.dll │ │ └── pthreadVC2.dll │ └── x86 │ │ ├── md5.sum │ │ ├── pthreadGC2.dll │ │ ├── pthreadVC2.dll │ │ ├── pthreadVCE2.dll │ │ └── pthreadVSE2.dll ├── include │ ├── md5.sum │ ├── pthread.h │ ├── sched.h │ └── semaphore.h └── lib │ ├── x64 │ ├── libpthreadGC2.a │ ├── md5.sum │ └── pthreadVC2.lib │ └── x86 │ ├── libpthreadGC2.a │ ├── md5.sum │ ├── pthreadVC2.lib │ ├── pthreadVCE2.lib │ └── pthreadVSE2.lib ├── rsp_tcp ├── IPAddress.cpp ├── IPAddress.h ├── MeasTimeDiff.cpp ├── MeasTimeDiff.h ├── common.cpp ├── common.h ├── controlThread.cpp ├── controlThread.h ├── devices.cpp ├── devices.h ├── getopt │ ├── getopt.c │ └── getopt.h ├── include_ext │ ├── md5.sum │ ├── mir_sdr.h │ ├── pthread.h │ ├── sched.h │ └── semaphore.h ├── lib32 │ ├── mir_sdr_api.dll │ ├── mir_sdr_api.lib │ ├── pthreadVC2.dll │ └── pthreadVC2.lib ├── lib64 │ ├── mir_sdr_api.dll │ ├── mir_sdr_api.lib │ ├── msvcr100.dll │ ├── pthreadVC2.dll │ └── pthreadVC2.lib ├── mir_sdr_device.cpp ├── mir_sdr_device.h ├── rsp_cmdLineArgs.cpp ├── rsp_cmdLineArgs.h ├── rsp_tcp.cpp ├── rsp_tcp.h ├── rsp_tcp.vcxproj ├── rsp_tcp.vcxproj.user ├── sdrGainTable.cpp ├── sdrGainTable.h └── syTwoDimArray.h └── x64 ├── Debug ├── RSP2_tcp.exe ├── mir_sdr_api.dll ├── msvcr100.dll └── pthreadVC2.dll └── Release ├── RSP2_tcp.exe ├── mir_sdr_api.dll ├── msvcr100.dll ├── pthreadVC2.dll └── runme.bat /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | /rsp_tcp/x64/Debug/RSP_tcp.tlog 6 | /rsp_tcp/x64/Debug 7 | /x64/Debug/RSP2_tcp.ilk 8 | /x64/Debug/RSP2_tcp.pdb 9 | /RSP_TCP.VC.db 10 | /RSP_TCP.VC.VC.opendb 11 | /rsp_tcp/x64/Release/RSP_tcp.tlog 12 | /rsp_tcp/x64/Release 13 | /.vs/RSP_TCP/v15/Solution.VC.db-wal 14 | /.vs/RSP_TCP/v15/Solution.VC.db-shm 15 | /.vs/RSP_TCP/v15/Solution.VC.db 16 | /.vs/RSP_TCP/v15/Browse.VC.opendb 17 | /.vs/RSP_TCP/v15/Browse.VC.db 18 | /.vs/RSP_TCP/v15/ipch/AutoPCH/a2c43de2d23bc1cb/RSP_TCP.ipch 19 | /.vs/RSP_TCP/v15/ipch/AutoPCH/7d56518f5a4ed131/MIR_SDR_DEVICE.ipch 20 | /.vs/RSP_TCP/v15/ipch/AutoPCH 21 | /x64/Release/RSP2_tcp.iobj 22 | /x64/Release/RSP2_tcp.ipdb 23 | /x64/Release/RSP2_tcp.pdb 24 | /.vs/RSP_TCP/v16/Solution.VC.db-wal 25 | /.vs/RSP_TCP/v16/Solution.VC.db-shm 26 | /.vs/RSP_TCP/v16/Solution.VC.db 27 | /.vs/RSP_TCP/v16/ipch/AutoPCH/1370a261582f2969/RSP_TCP.ipch 28 | /.vs/RSP_TCP/v16/Browse.VC.opendb 29 | /.vs/RSP_TCP/v16/Browse.VC.db-wal 30 | /.vs/RSP_TCP/v16/Browse.VC.db-shm 31 | /.vs/RSP_TCP/v16/Browse.VC.db 32 | /x64/Release/RSP2_tcp.zip 33 | /.vs/RSP_TCP/v16/ipch/AutoPCH 34 | /.vs/RSP_TCP/v16/.suo 35 | /rsp_tcp.zip 36 | -------------------------------------------------------------------------------- /.vs/RSP_TCP/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/.vs/RSP_TCP/v15/.suo -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RSP2_tcp 2 | TCP/IP Server for I/Q data delivered by sdrplay RSP devices : RSP1 (untested), RSP1A, RSP2, RSPduo (single tuner) 3 | - Compatible to rtl_tcp, 4 | - Runs on Windows and Linux, 5 | - Delivers 8- and 16- Bit I/Q Data, 6 | - Compatible with SDR# (8-Bit Mode, Source RTL-SDR (TCP)) 7 | - Working with sdrplay driver 2.13. 8 | ## History 9 | ### January 2022 10 | - [QIRX](https://qirx.softsyst.com) from its Version 3.2.1 now uses [RSP3_tcp](https://github.com/softsyst/RSP3_tcp), interfacing to the V3.09 of sdrplay's API. 11 | - RSP2_tcp will not be further developed. 12 | ### V0.9.13, September 2021 13 | - Fractional ppm correction also applied to the sampling rate. 14 | ### V0.9.12, August 2021 15 | - New command 0x4A, setting the PPM in units of 1/100. 16 | ### V0.9.11, July 2021 17 | - Back Channel for reporting from RSP2_tcp back to the client 18 | ### V0.9.10, June 2021 19 | - Verbose output on Frequency and Gain Settings configurable 20 | - Waiting sleep in Set Frequency removed. 21 | ### V0.9.9, October 2020 22 | - Gain steps changed from 99 to 80 23 | - AGC Algorithm revised 24 | - Time Measurements possible with conditional compilation 25 | ### V0.9.7, November 2019 26 | - Version necessary for QIRX V2.1.1.6 running RSPs 27 | - BiasT, 28 | - Antenna selection mapped to tuner selection in the RSPduo 29 | - Minor errors in gain table fixed### V0.9.7, November 2019 30 | - Gain settings for the commandline argument cleaned, 31 | ### V0.9.6, June 2019 32 | - Gain settings revised, RSP1(A) should now work much better, 33 | - RSP2duo newly supported. 34 | 35 | **Credits:** 36 | - Thanks to Herman Wijnants (http://www.wijnants.info/fmdx) for his extensive tests of the revised gain settings, 37 | - Thanks to Martien, PD1G for his testing of the program with the RSPduo. 38 | -------------------------------------------------------------------------------- /RSP_TCP.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RSP_tcp", "rsp_tcp\rsp_tcp.vcxproj", "{09435408-8689-459B-87FF-2EB61FAEB665}" 7 | EndProject 8 | Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "RSP_tcp_setup", "RSP_tcp_setup\sdr_tcp_setup.vdproj", "{B1B3CF51-9CA1-4022-82E5-5042F0268A08}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {09435408-8689-459B-87FF-2EB61FAEB665}.Debug|x64.ActiveCfg = Debug|x64 19 | {09435408-8689-459B-87FF-2EB61FAEB665}.Debug|x64.Build.0 = Debug|x64 20 | {09435408-8689-459B-87FF-2EB61FAEB665}.Debug|x86.ActiveCfg = Debug|Win32 21 | {09435408-8689-459B-87FF-2EB61FAEB665}.Debug|x86.Build.0 = Debug|Win32 22 | {09435408-8689-459B-87FF-2EB61FAEB665}.Release|x64.ActiveCfg = Release|x64 23 | {09435408-8689-459B-87FF-2EB61FAEB665}.Release|x64.Build.0 = Release|x64 24 | {09435408-8689-459B-87FF-2EB61FAEB665}.Release|x86.ActiveCfg = Release|Win32 25 | {09435408-8689-459B-87FF-2EB61FAEB665}.Release|x86.Build.0 = Release|Win32 26 | {B1B3CF51-9CA1-4022-82E5-5042F0268A08}.Debug|x64.ActiveCfg = Debug 27 | {B1B3CF51-9CA1-4022-82E5-5042F0268A08}.Debug|x64.Build.0 = Debug 28 | {B1B3CF51-9CA1-4022-82E5-5042F0268A08}.Debug|x86.ActiveCfg = Debug 29 | {B1B3CF51-9CA1-4022-82E5-5042F0268A08}.Debug|x86.Build.0 = Debug 30 | {B1B3CF51-9CA1-4022-82E5-5042F0268A08}.Release|x64.ActiveCfg = Release 31 | {B1B3CF51-9CA1-4022-82E5-5042F0268A08}.Release|x64.Build.0 = Release 32 | {B1B3CF51-9CA1-4022-82E5-5042F0268A08}.Release|x86.ActiveCfg = Release 33 | {B1B3CF51-9CA1-4022-82E5-5042F0268A08}.Release|x86.Build.0 = Release 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /RSP_tcp_setup/Debug/sdr_tcp_setup.msi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/RSP_tcp_setup/Debug/sdr_tcp_setup.msi -------------------------------------------------------------------------------- /RSP_tcp_setup/Debug/setup.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/RSP_tcp_setup/Debug/setup.exe -------------------------------------------------------------------------------- /RSP_tcp_setup/Release/RSP_tcp_setup.msi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/RSP_tcp_setup/Release/RSP_tcp_setup.msi -------------------------------------------------------------------------------- /RSP_tcp_setup/Release/setup.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/RSP_tcp_setup/Release/setup.exe -------------------------------------------------------------------------------- /Release/RSP_tcp.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/Release/RSP_tcp.exe -------------------------------------------------------------------------------- /Release/mir_sdr_api.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/Release/mir_sdr_api.dll -------------------------------------------------------------------------------- /Release/msvcr100.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/Release/msvcr100.dll -------------------------------------------------------------------------------- /Release/pthreadVC2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/Release/pthreadVC2.dll -------------------------------------------------------------------------------- /Release/runme.bat: -------------------------------------------------------------------------------- 1 | RSP_tcp.exe -a 127.0.0.1 -p 1234 -W 1 -g 23 -------------------------------------------------------------------------------- /SDRplay_RSP_API_Release_Notes_V2.13.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/SDRplay_RSP_API_Release_Notes_V2.13.pdf -------------------------------------------------------------------------------- /mirics_API/inc/mir_sdr.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2013 Mirics Ltd, All Rights Reserved 3 | // 4 | 5 | #ifndef MIR_SDR_H 6 | #define MIR_SDR_H 7 | 8 | #ifndef _MIR_SDR_QUALIFIER 9 | #if !defined(STATIC_LIB) && (defined(_M_X64) || defined(_M_IX86)) 10 | #define _MIR_SDR_QUALIFIER __declspec(dllimport) 11 | #elif defined(STATIC_LIB) || defined(__GNUC__) 12 | #define _MIR_SDR_QUALIFIER 13 | #endif 14 | #endif // _MIR_SDR_QUALIFIER 15 | 16 | // Application code should check that it is compiled against the same API version 17 | // mir_sdr_ApiVersion() returns the API version 18 | #define MIR_SDR_API_VERSION (float)(2.13) 19 | 20 | #if defined(ANDROID) || defined(__ANDROID__) 21 | // Android requires a mechanism to request info from Java application 22 | typedef enum 23 | { 24 | mir_sdr_GetFd = 0, 25 | mir_sdr_FreeFd = 1, 26 | mir_sdr_DevNotFound = 2, 27 | mir_sdr_DevRemoved = 3, 28 | mir_sdr_GetVendorId = 4, 29 | mir_sdr_GetProductId = 5, 30 | mir_sdr_GetRevId = 6, 31 | mir_sdr_GetDeviceId = 7 32 | } mir_sdr_JavaReqT; 33 | 34 | typedef int (*mir_sdr_SendJavaReq_t)(mir_sdr_JavaReqT cmd, char *path, char *serNum); 35 | #endif 36 | 37 | typedef enum 38 | { 39 | mir_sdr_Success = 0, 40 | mir_sdr_Fail = 1, 41 | mir_sdr_InvalidParam = 2, 42 | mir_sdr_OutOfRange = 3, 43 | mir_sdr_GainUpdateError = 4, 44 | mir_sdr_RfUpdateError = 5, 45 | mir_sdr_FsUpdateError = 6, 46 | mir_sdr_HwError = 7, 47 | mir_sdr_AliasingError = 8, 48 | mir_sdr_AlreadyInitialised = 9, 49 | mir_sdr_NotInitialised = 10, 50 | mir_sdr_NotEnabled = 11, 51 | mir_sdr_HwVerError = 12, 52 | mir_sdr_OutOfMemError = 13, 53 | mir_sdr_HwRemoved = 14 54 | } mir_sdr_ErrT; 55 | 56 | typedef enum 57 | { 58 | mir_sdr_BW_Undefined = 0, 59 | mir_sdr_BW_0_200 = 200, 60 | mir_sdr_BW_0_300 = 300, 61 | mir_sdr_BW_0_600 = 600, 62 | mir_sdr_BW_1_536 = 1536, 63 | mir_sdr_BW_5_000 = 5000, 64 | mir_sdr_BW_6_000 = 6000, 65 | mir_sdr_BW_7_000 = 7000, 66 | mir_sdr_BW_8_000 = 8000 67 | } mir_sdr_Bw_MHzT; 68 | 69 | typedef enum 70 | { 71 | mir_sdr_IF_Undefined = -1, 72 | mir_sdr_IF_Zero = 0, 73 | mir_sdr_IF_0_450 = 450, 74 | mir_sdr_IF_1_620 = 1620, 75 | mir_sdr_IF_2_048 = 2048 76 | } mir_sdr_If_kHzT; 77 | 78 | typedef enum 79 | { 80 | mir_sdr_ISOCH = 0, 81 | mir_sdr_BULK = 1 82 | } mir_sdr_TransferModeT; 83 | 84 | typedef enum 85 | { 86 | mir_sdr_CHANGE_NONE = 0x00, 87 | mir_sdr_CHANGE_GR = 0x01, 88 | mir_sdr_CHANGE_FS_FREQ = 0x02, 89 | mir_sdr_CHANGE_RF_FREQ = 0x04, 90 | mir_sdr_CHANGE_BW_TYPE = 0x08, 91 | mir_sdr_CHANGE_IF_TYPE = 0x10, 92 | mir_sdr_CHANGE_LO_MODE = 0x20, 93 | mir_sdr_CHANGE_AM_PORT = 0x40 94 | } mir_sdr_ReasonForReinitT; 95 | 96 | typedef enum 97 | { 98 | mir_sdr_LO_Undefined = 0, 99 | mir_sdr_LO_Auto = 1, 100 | mir_sdr_LO_120MHz = 2, 101 | mir_sdr_LO_144MHz = 3, 102 | mir_sdr_LO_168MHz = 4 103 | } mir_sdr_LoModeT; 104 | 105 | typedef enum 106 | { 107 | mir_sdr_BAND_AM_LO = 0, 108 | mir_sdr_BAND_AM_MID = 1, 109 | mir_sdr_BAND_AM_HI = 2, 110 | mir_sdr_BAND_VHF = 3, 111 | mir_sdr_BAND_3 = 4, 112 | mir_sdr_BAND_X = 5, 113 | mir_sdr_BAND_4_5 = 6, 114 | mir_sdr_BAND_L = 7 115 | } mir_sdr_BandT; 116 | 117 | typedef enum 118 | { 119 | mir_sdr_USE_SET_GR = 0, 120 | mir_sdr_USE_SET_GR_ALT_MODE = 1, 121 | mir_sdr_USE_RSP_SET_GR = 2 122 | } mir_sdr_SetGrModeT; 123 | 124 | typedef enum 125 | { 126 | mir_sdr_RSPII_BAND_UNKNOWN = 0, 127 | mir_sdr_RSPII_BAND_AM_LO = 1, 128 | mir_sdr_RSPII_BAND_AM_MID = 2, 129 | mir_sdr_RSPII_BAND_AM_HI = 3, 130 | mir_sdr_RSPII_BAND_VHF = 4, 131 | mir_sdr_RSPII_BAND_3 = 5, 132 | mir_sdr_RSPII_BAND_X_LO = 6, 133 | mir_sdr_RSPII_BAND_X_MID = 7, 134 | mir_sdr_RSPII_BAND_X_HI = 8, 135 | mir_sdr_RSPII_BAND_4_5 = 9, 136 | mir_sdr_RSPII_BAND_L = 10 137 | } mir_sdr_RSPII_BandT; 138 | 139 | typedef enum 140 | { 141 | mir_sdr_RSPII_ANTENNA_A = 5, 142 | mir_sdr_RSPII_ANTENNA_B = 6 143 | } mir_sdr_RSPII_AntennaSelectT; 144 | 145 | typedef enum 146 | { 147 | mir_sdr_AGC_DISABLE = 0, 148 | mir_sdr_AGC_100HZ = 1, 149 | mir_sdr_AGC_50HZ = 2, 150 | mir_sdr_AGC_5HZ = 3 151 | } mir_sdr_AgcControlT; 152 | 153 | typedef enum 154 | { 155 | mir_sdr_GAIN_MESSAGE_START_ID = 0x80000000, 156 | mir_sdr_ADC_OVERLOAD_DETECTED = mir_sdr_GAIN_MESSAGE_START_ID + 1, 157 | mir_sdr_ADC_OVERLOAD_CORRECTED = mir_sdr_GAIN_MESSAGE_START_ID + 2 158 | } mir_sdr_GainMessageIdT; 159 | 160 | typedef enum 161 | { 162 | mir_sdr_EXTENDED_MIN_GR = 0, 163 | mir_sdr_NORMAL_MIN_GR = 20 164 | } mir_sdr_MinGainReductionT; 165 | 166 | typedef struct 167 | { 168 | char *SerNo; 169 | char *DevNm; 170 | unsigned char hwVer; 171 | unsigned char devAvail; 172 | } mir_sdr_DeviceT; 173 | 174 | typedef struct 175 | { 176 | float curr; 177 | float max; 178 | float min; 179 | } mir_sdr_GainValuesT; 180 | 181 | typedef enum 182 | { 183 | mir_sdr_rspDuo_Tuner_1 = 1, 184 | mir_sdr_rspDuo_Tuner_2 = 2, 185 | } mir_sdr_rspDuo_TunerSelT; 186 | 187 | // mir_sdr_StreamInit() callback function prototypes 188 | typedef void (*mir_sdr_StreamCallback_t)(short *xi, short *xq, unsigned int firstSampleNum, int grChanged, int rfChanged, int fsChanged, unsigned int numSamples, unsigned int reset, unsigned int hwRemoved, void *cbContext); 189 | typedef void (*mir_sdr_GainChangeCallback_t)(unsigned int gRdB, unsigned int lnaGRdB, void *cbContext); 190 | 191 | typedef mir_sdr_ErrT (*mir_sdr_Init_t)(int gRdB, double fsMHz, double rfMHz, mir_sdr_Bw_MHzT bwType, mir_sdr_If_kHzT ifType, int *samplesPerPacket); 192 | typedef mir_sdr_ErrT (*mir_sdr_Uninit_t)(void); 193 | typedef mir_sdr_ErrT (*mir_sdr_ReadPacket_t)(short *xi, short *xq, unsigned int *firstSampleNum, int *grChanged, int *rfChanged, int *fsChanged); 194 | typedef mir_sdr_ErrT (*mir_sdr_SetRf_t)(double drfHz, int abs, int syncUpdate); 195 | typedef mir_sdr_ErrT (*mir_sdr_SetFs_t)(double dfsHz, int abs, int syncUpdate, int reCal); 196 | typedef mir_sdr_ErrT (*mir_sdr_SetGr_t)(int gRdB, int abs, int syncUpdate); 197 | typedef mir_sdr_ErrT (*mir_sdr_SetGrParams_t)(int minimumGr, int lnaGrThreshold); 198 | typedef mir_sdr_ErrT (*mir_sdr_SetDcMode_t)(int dcCal, int speedUp); 199 | typedef mir_sdr_ErrT (*mir_sdr_SetDcTrackTime_t)(int trackTime); 200 | typedef mir_sdr_ErrT (*mir_sdr_SetSyncUpdateSampleNum_t)(unsigned int sampleNum); 201 | typedef mir_sdr_ErrT (*mir_sdr_SetSyncUpdatePeriod_t)(unsigned int period); 202 | typedef mir_sdr_ErrT (*mir_sdr_ApiVersion_t)(float *version); 203 | typedef mir_sdr_ErrT (*mir_sdr_ResetUpdateFlags_t)(int resetGainUpdate, int resetRfUpdate, int resetFsUpdate); 204 | #if defined(ANDROID) || defined(__ANDROID__) 205 | typedef mir_sdr_ErrT (*mir_sdr_SetJavaReqCallback_t)(mir_sdr_SendJavaReq_t sendJavaReq); 206 | #endif 207 | typedef mir_sdr_ErrT (*mir_sdr_SetTransferMode_t)(mir_sdr_TransferModeT mode); 208 | typedef mir_sdr_ErrT (*mir_sdr_DownConvert_t)(short *in, short *xi, short *xq, unsigned int samplesPerPacket, mir_sdr_If_kHzT ifType, unsigned int M, unsigned int preReset); 209 | typedef mir_sdr_ErrT (*mir_sdr_SetParam_t)(unsigned int id, unsigned int value); 210 | typedef mir_sdr_ErrT (*mir_sdr_SetPpm_t)(double ppm); 211 | typedef mir_sdr_ErrT (*mir_sdr_SetLoMode_t)(mir_sdr_LoModeT loMode); 212 | typedef mir_sdr_ErrT (*mir_sdr_SetGrAltMode_t)(int *gRidx, int LNAstate, int *gRdBsystem, int abs, int syncUpdate); 213 | typedef mir_sdr_ErrT (*mir_sdr_DCoffsetIQimbalanceControl_t)(unsigned int DCenable, unsigned int IQenable); 214 | typedef mir_sdr_ErrT (*mir_sdr_DecimateControl_t)(unsigned int enable, unsigned int decimationFactor, unsigned int wideBandSignal); 215 | typedef mir_sdr_ErrT (*mir_sdr_AgcControl_t)(mir_sdr_AgcControlT enable, int setPoint_dBfs, int knee_dBfs, unsigned int decay_ms, unsigned int hang_ms, int syncUpdate, int LNAstate); 216 | typedef mir_sdr_ErrT (*mir_sdr_StreamInit_t)(int *gRdB, double fsMHz, double rfMHz, mir_sdr_Bw_MHzT bwType, mir_sdr_If_kHzT ifType, int LNAstate, int *gRdBsystem, mir_sdr_SetGrModeT setGrMode, int *samplesPerPacket, mir_sdr_StreamCallback_t StreamCbFn, mir_sdr_GainChangeCallback_t GainChangeCbFn, void *cbContext); 217 | typedef mir_sdr_ErrT (*mir_sdr_StreamUninit_t)(void); 218 | typedef mir_sdr_ErrT (*mir_sdr_Reinit_t)(int *gRdB, double fsMHz, double rfMHz, mir_sdr_Bw_MHzT bwType, mir_sdr_If_kHzT ifType, mir_sdr_LoModeT loMode, int LNAstate, int *gRdBsystem, mir_sdr_SetGrModeT setGrMode, int *samplesPerPacket, mir_sdr_ReasonForReinitT reasonForReinit); 219 | typedef mir_sdr_ErrT (*mir_sdr_GetGrByFreq_t)(double rfMHz, mir_sdr_BandT *band, int *gRdB, int LNAstate, int *gRdBsystem, mir_sdr_SetGrModeT setGrMode); 220 | typedef mir_sdr_ErrT (*mir_sdr_DebugEnable_t)(unsigned int enable); 221 | typedef mir_sdr_ErrT (*mir_sdr_GetCurrentGain_t)(mir_sdr_GainValuesT *gainVals); 222 | typedef mir_sdr_ErrT (*mir_sdr_GainChangeCallbackMessageReceived_t)(void); 223 | 224 | typedef mir_sdr_ErrT (*mir_sdr_GetDevices_t)(mir_sdr_DeviceT *devices, unsigned int *numDevs, unsigned int maxDevs); 225 | typedef mir_sdr_ErrT (*mir_sdr_SetDeviceIdx_t)(unsigned int idx); 226 | typedef mir_sdr_ErrT (*mir_sdr_ReleaseDeviceIdx_t)(void); 227 | typedef mir_sdr_ErrT (*mir_sdr_GetHwVersion_t)(unsigned char *ver); 228 | typedef mir_sdr_ErrT (*mir_sdr_RSPII_AntennaControl_t)(mir_sdr_RSPII_AntennaSelectT select); 229 | typedef mir_sdr_ErrT (*mir_sdr_RSPII_ExternalReferenceControl_t)(unsigned int output_enable); 230 | typedef mir_sdr_ErrT (*mir_sdr_RSPII_BiasTControl_t)(unsigned int enable); 231 | typedef mir_sdr_ErrT (*mir_sdr_RSPII_RfNotchEnable_t)(unsigned int enable); 232 | 233 | typedef mir_sdr_ErrT (*mir_sdr_RSP_SetGr_t)(int gRdB, int LNAstate, int abs, int syncUpdate); 234 | typedef mir_sdr_ErrT (*mir_sdr_RSP_SetGrLimits_t)(mir_sdr_MinGainReductionT minGr); 235 | 236 | typedef mir_sdr_ErrT (*mir_sdr_AmPortSelect_t)(int port); 237 | 238 | typedef mir_sdr_ErrT (*mir_sdr_rsp1a_BiasT_t)(int enable); 239 | typedef mir_sdr_ErrT (*mir_sdr_rsp1a_DabNotch_t)(int enable); 240 | typedef mir_sdr_ErrT (*mir_sdr_rsp1a_BroadcastNotch_t)(int enable); 241 | 242 | typedef mir_sdr_ErrT (*mir_sdr_rspDuo_TunerSel_t)(mir_sdr_rspDuo_TunerSelT sel); 243 | typedef mir_sdr_ErrT (*mir_sdr_rspDuo_ExtRef_t)(int enable); 244 | typedef mir_sdr_ErrT (*mir_sdr_rspDuo_BiasT_t)(int enable); 245 | typedef mir_sdr_ErrT (*mir_sdr_rspDuo_Tuner1AmNotch_t)(int enable); 246 | typedef mir_sdr_ErrT (*mir_sdr_rspDuo_BroadcastNotch_t)(int enable); 247 | typedef mir_sdr_ErrT (*mir_sdr_rspDuo_DabNotch_t)(int enable); 248 | 249 | // API function definitions 250 | #ifdef __cplusplus 251 | extern "C" 252 | { 253 | #endif 254 | 255 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_Init(int gRdB, double fsMHz, double rfMHz, mir_sdr_Bw_MHzT bwType, mir_sdr_If_kHzT ifType, int *samplesPerPacket); 256 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_Uninit(void); 257 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_ReadPacket(short *xi, short *xq, unsigned int *firstSampleNum, int *grChanged, int *rfChanged, int *fsChanged); 258 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetRf(double drfHz, int abs, int syncUpdate); 259 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetFs(double dfsHz, int abs, int syncUpdate, int reCal); 260 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetGr(int gRdB, int abs, int syncUpdate); 261 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetGrParams(int minimumGr, int lnaGrThreshold); 262 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetDcMode(int dcCal, int speedUp); 263 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetDcTrackTime(int trackTime); 264 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetSyncUpdateSampleNum(unsigned int sampleNum); 265 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetSyncUpdatePeriod(unsigned int period); 266 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_ApiVersion(float *version); // Called by application to retrieve version of API used to create Dll 267 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_ResetUpdateFlags(int resetGainUpdate, int resetRfUpdate, int resetFsUpdate); 268 | #if defined(ANDROID) || defined(__ANDROID__) 269 | // This function provides a machanism for the Java application to set 270 | // the callback function used to send request to it 271 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetJavaReqCallback(mir_sdr_SendJavaReq_t sendJavaReq); 272 | #endif 273 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetTransferMode(mir_sdr_TransferModeT mode); 274 | /* 275 | * This following function will only operate correctly for the parameters detailed in the table below: 276 | * 277 | * IF freq | Signal BW | Input Sample Rate | Output Sample Rate | Required Decimation Factor 278 | * ------------------------------------------------------------------------------------------- 279 | * 450kHz | 200kHz | 2000kHz | 500kHz | M=4 280 | * 450kHz | 300kHz | 2000kHz | 500kHz | M=4 281 | * 450kHz | 600kHz | 2000kHz | 1000kHz | M=2 282 | * 2048kHz | 1536kHz | 8192kHz | 2048kHz | M=4 283 | * 284 | * If preReset == 1, then the filter state will be reset to 0 before starting the filtering operation. 285 | */ 286 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_DownConvert(short *in, short *xi, short *xq, unsigned int samplesPerPacket, mir_sdr_If_kHzT ifType, unsigned int M, unsigned int preReset); 287 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetParam(unsigned int id, unsigned int value); // This MAY be called before mir_sdr_Init() 288 | 289 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetPpm(double ppm); // This MAY be called before mir_sdr_Init() 290 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetLoMode(mir_sdr_LoModeT loMode); // This MUST be called before mir_sdr_Init()/mir_sdr_StreamInit() - otherwise use mir_sdr_Reinit() 291 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetGrAltMode(int *gRidx, int LNAstate, int *gRdBsystem, int abs, int syncUpdate); 292 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_DCoffsetIQimbalanceControl(unsigned int DCenable, unsigned int IQenable); 293 | /* 294 | * Valid decimation factors for the following function are 2, 4, 8, 16 or 32 only 295 | * Setting wideBandSignal=1 will use a slower filter but minimise the in-band roll-off 296 | */ 297 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_DecimateControl(unsigned int enable, unsigned int decimationFactor, unsigned int wideBandSignal); 298 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_AgcControl(mir_sdr_AgcControlT enable, int setPoint_dBfs, int knee_dBfs, unsigned int decay_ms, unsigned int hang_ms, int syncUpdate, int LNAstate); 299 | /* 300 | * mir_sdr_StreamInit() replaces mir_sdr_Init() and sets up a thread (or chain of threads) inside the API which will perform the processing chain (shown below), 301 | * and then use the callback function to return the data to the calling application/plug-in. 302 | * Processing chain (in order): 303 | * mir_sdr_ReadPacket() 304 | * DCoffsetCorrection() - LIF mode - enabled by default 305 | * DownConvert() - automatically enabled if the parameters shown for mir_sdr_DownConvert() are selected 306 | * Decimate() - disabled by default 307 | * DCoffsetCorrection() - ZIF mode - enabled by default 308 | * IQimbalanceCorrection() - enabled by default 309 | * Agc() - disabled by default 310 | */ 311 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_StreamInit(int *gRdB, double fsMHz, double rfMHz, mir_sdr_Bw_MHzT bwType, mir_sdr_If_kHzT ifType, int LNAstate, int *gRdBsystem, mir_sdr_SetGrModeT setGrMode, int *samplesPerPacket, mir_sdr_StreamCallback_t StreamCbFn, mir_sdr_GainChangeCallback_t GainChangeCbFn, void *cbContext); 312 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_StreamUninit(void); 313 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_Reinit(int *gRdB, double fsMHz, double rfMHz, mir_sdr_Bw_MHzT bwType, mir_sdr_If_kHzT ifType, mir_sdr_LoModeT loMode, int LNAstate, int *gRdBsystem, mir_sdr_SetGrModeT setGrMode, int *samplesPerPacket, mir_sdr_ReasonForReinitT reasonForReinit); 314 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_GetGrByFreq(double rfMHz, mir_sdr_BandT *band, int *gRdB, int LNAstate, int *gRdBsystem, mir_sdr_SetGrModeT setGrMode); 315 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_DebugEnable(unsigned int enable); 316 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_GetCurrentGain(mir_sdr_GainValuesT *gainVals); 317 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_GainChangeCallbackMessageReceived(void); 318 | 319 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_GetDevices(mir_sdr_DeviceT *devices, unsigned int *numDevs, unsigned int maxDevs); 320 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetDeviceIdx(unsigned int idx); 321 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_ReleaseDeviceIdx(void); 322 | /* 323 | * Uninit: ver = 0 324 | * RSPI : ver = 1 325 | * RSPII: ver = 2 326 | */ 327 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_GetHwVersion(unsigned char *ver); 328 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_RSPII_AntennaControl(mir_sdr_RSPII_AntennaSelectT select); 329 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_RSPII_ExternalReferenceControl(unsigned int output_enable); 330 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_RSPII_BiasTControl(unsigned int enable); 331 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_RSPII_RfNotchEnable(unsigned int enable); 332 | 333 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_RSP_SetGr(int gRdB, int LNAstate, int abs, int syncUpdate); 334 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_RSP_SetGrLimits(mir_sdr_MinGainReductionT minGr); 335 | 336 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_AmPortSelect(int port); // If called after mir_sdr_Init() a call to mir_sdr_Reinit(..., reasonForReinit = mir_sdr_CHANGE_AM_PORT) 337 | // is also required to change the port 338 | 339 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rsp1a_BiasT(int enable); 340 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rsp1a_DabNotch(int enable); 341 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rsp1a_BroadcastNotch(int enable); 342 | 343 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rspDuo_TunerSel(mir_sdr_rspDuo_TunerSelT sel); 344 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rspDuo_ExtRef(int enable); 345 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rspDuo_BiasT(int enable); 346 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rspDuo_Tuner1AmNotch(int enable); 347 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rspDuo_BroadcastNotch(int enable); 348 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rspDuo_DabNotch(int enable); 349 | 350 | #ifdef __cplusplus 351 | } 352 | #endif 353 | 354 | #endif //MIR_SDR_H 355 | -------------------------------------------------------------------------------- /mirics_API/x64/mir_sdr_api.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/mirics_API/x64/mir_sdr_api.dll -------------------------------------------------------------------------------- /mirics_API/x64/mir_sdr_api.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/mirics_API/x64/mir_sdr_api.lib -------------------------------------------------------------------------------- /mirics_API/x86/mir_sdr_api.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/mirics_API/x86/mir_sdr_api.dll -------------------------------------------------------------------------------- /mirics_API/x86/mir_sdr_api.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/mirics_API/x86/mir_sdr_api.lib -------------------------------------------------------------------------------- /posix/dll/x64/md5.sum: -------------------------------------------------------------------------------- 1 | a8e566e3a09e9451c6d2c531758a5758 pthreadGC2.dll 2 | 4a502706d149c2f5854131a7758a90e2 pthreadVC2.dll 3 | -------------------------------------------------------------------------------- /posix/dll/x64/pthreadGC2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/posix/dll/x64/pthreadGC2.dll -------------------------------------------------------------------------------- /posix/dll/x64/pthreadVC2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/posix/dll/x64/pthreadVC2.dll -------------------------------------------------------------------------------- /posix/dll/x86/md5.sum: -------------------------------------------------------------------------------- 1 | 72c1ff7f3c7474850b11fc962ee1620c pthreadGC2.dll 2 | cf03305003c7338722d66fc48defaa69 pthreadGCE2.dll 3 | 7812f0f73eda837e9353b3a433abc9a9 pthreadVC2.dll 4 | d293c1e469fb7e0ea44b8f64bec49634 pthreadVCE2.dll 5 | db01f7552cf07fade57c3d494b65cacf pthreadVSE2.dll 6 | -------------------------------------------------------------------------------- /posix/dll/x86/pthreadGC2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/posix/dll/x86/pthreadGC2.dll -------------------------------------------------------------------------------- /posix/dll/x86/pthreadVC2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/posix/dll/x86/pthreadVC2.dll -------------------------------------------------------------------------------- /posix/dll/x86/pthreadVCE2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/posix/dll/x86/pthreadVCE2.dll -------------------------------------------------------------------------------- /posix/dll/x86/pthreadVSE2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/posix/dll/x86/pthreadVSE2.dll -------------------------------------------------------------------------------- /posix/include/md5.sum: -------------------------------------------------------------------------------- 1 | cfdb57a8e93ee1ed9322908f49a750d5 pthread.h 2 | 37cb7e0c214b62b37a57ab46d72e1034 sched.h 3 | 2c928d43a30ca0b0ad39a0accbae775e semaphore.h 4 | -------------------------------------------------------------------------------- /posix/include/sched.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Module: sched.h 3 | * 4 | * Purpose: 5 | * Provides an implementation of POSIX realtime extensions 6 | * as defined in 7 | * 8 | * POSIX 1003.1b-1993 (POSIX.1b) 9 | * 10 | * -------------------------------------------------------------------------- 11 | * 12 | * Pthreads-win32 - POSIX Threads Library for Win32 13 | * Copyright(C) 1998 John E. Bossom 14 | * Copyright(C) 1999,2005 Pthreads-win32 contributors 15 | * 16 | * Contact Email: rpj@callisto.canberra.edu.au 17 | * 18 | * The current list of contributors is contained 19 | * in the file CONTRIBUTORS included with the source 20 | * code distribution. The list can also be seen at the 21 | * following World Wide Web location: 22 | * http://sources.redhat.com/pthreads-win32/contributors.html 23 | * 24 | * This library is free software; you can redistribute it and/or 25 | * modify it under the terms of the GNU Lesser General Public 26 | * License as published by the Free Software Foundation; either 27 | * version 2 of the License, or (at your option) any later version. 28 | * 29 | * This library is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 32 | * Lesser General Public License for more details. 33 | * 34 | * You should have received a copy of the GNU Lesser General Public 35 | * License along with this library in the file COPYING.LIB; 36 | * if not, write to the Free Software Foundation, Inc., 37 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 38 | */ 39 | #if !defined(_SCHED_H) 40 | #define _SCHED_H 41 | 42 | #undef PTW32_SCHED_LEVEL 43 | 44 | #if defined(_POSIX_SOURCE) 45 | #define PTW32_SCHED_LEVEL 0 46 | /* Early POSIX */ 47 | #endif 48 | 49 | #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 50 | #undef PTW32_SCHED_LEVEL 51 | #define PTW32_SCHED_LEVEL 1 52 | /* Include 1b, 1c and 1d */ 53 | #endif 54 | 55 | #if defined(INCLUDE_NP) 56 | #undef PTW32_SCHED_LEVEL 57 | #define PTW32_SCHED_LEVEL 2 58 | /* Include Non-Portable extensions */ 59 | #endif 60 | 61 | #define PTW32_SCHED_LEVEL_MAX 3 62 | 63 | #if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_SCHED_LEVEL) 64 | #define PTW32_SCHED_LEVEL PTW32_SCHED_LEVEL_MAX 65 | /* Include everything */ 66 | #endif 67 | 68 | 69 | #if defined(__GNUC__) && !defined(__declspec) 70 | # error Please upgrade your GNU compiler to one that supports __declspec. 71 | #endif 72 | 73 | /* 74 | * When building the library, you should define PTW32_BUILD so that 75 | * the variables/functions are exported correctly. When using the library, 76 | * do NOT define PTW32_BUILD, and then the variables/functions will 77 | * be imported correctly. 78 | */ 79 | #if !defined(PTW32_STATIC_LIB) 80 | # if defined(PTW32_BUILD) 81 | # define PTW32_DLLPORT __declspec (dllexport) 82 | # else 83 | # define PTW32_DLLPORT __declspec (dllimport) 84 | # endif 85 | #else 86 | # define PTW32_DLLPORT 87 | #endif 88 | 89 | /* 90 | * This is a duplicate of what is in the autoconf config.h, 91 | * which is only used when building the pthread-win32 libraries. 92 | */ 93 | 94 | #if !defined(PTW32_CONFIG_H) 95 | # if defined(WINCE) 96 | # define NEED_ERRNO 97 | # define NEED_SEM 98 | # endif 99 | # if defined(__MINGW64__) 100 | # define HAVE_STRUCT_TIMESPEC 101 | # define HAVE_MODE_T 102 | # elif defined(_UWIN) || defined(__MINGW32__) 103 | # define HAVE_MODE_T 104 | # endif 105 | #endif 106 | 107 | /* 108 | * 109 | */ 110 | 111 | #if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX 112 | #if defined(NEED_ERRNO) 113 | #include "need_errno.h" 114 | #else 115 | #include 116 | #endif 117 | #endif /* PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX */ 118 | 119 | #if (defined(__MINGW64__) || defined(__MINGW32__)) || defined(_UWIN) 120 | # if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX 121 | /* For pid_t */ 122 | # include 123 | /* Required by Unix 98 */ 124 | # include 125 | # else 126 | typedef int pid_t; 127 | # endif 128 | #else 129 | typedef int pid_t; 130 | #endif 131 | 132 | /* Thread scheduling policies */ 133 | 134 | enum { 135 | SCHED_OTHER = 0, 136 | SCHED_FIFO, 137 | SCHED_RR, 138 | SCHED_MIN = SCHED_OTHER, 139 | SCHED_MAX = SCHED_RR 140 | }; 141 | 142 | struct sched_param { 143 | int sched_priority; 144 | }; 145 | 146 | #if defined(__cplusplus) 147 | extern "C" 148 | { 149 | #endif /* __cplusplus */ 150 | 151 | PTW32_DLLPORT int __cdecl sched_yield (void); 152 | 153 | PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy); 154 | 155 | PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy); 156 | 157 | PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy); 158 | 159 | PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid); 160 | 161 | /* 162 | * Note that this macro returns ENOTSUP rather than 163 | * ENOSYS as might be expected. However, returning ENOSYS 164 | * should mean that sched_get_priority_{min,max} are 165 | * not implemented as well as sched_rr_get_interval. 166 | * This is not the case, since we just don't support 167 | * round-robin scheduling. Therefore I have chosen to 168 | * return the same value as sched_setscheduler when 169 | * SCHED_RR is passed to it. 170 | */ 171 | #define sched_rr_get_interval(_pid, _interval) \ 172 | ( errno = ENOTSUP, (int) -1 ) 173 | 174 | 175 | #if defined(__cplusplus) 176 | } /* End of extern "C" */ 177 | #endif /* __cplusplus */ 178 | 179 | #undef PTW32_SCHED_LEVEL 180 | #undef PTW32_SCHED_LEVEL_MAX 181 | 182 | #endif /* !_SCHED_H */ 183 | 184 | -------------------------------------------------------------------------------- /posix/include/semaphore.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Module: semaphore.h 3 | * 4 | * Purpose: 5 | * Semaphores aren't actually part of the PThreads standard. 6 | * They are defined by the POSIX Standard: 7 | * 8 | * POSIX 1003.1b-1993 (POSIX.1b) 9 | * 10 | * -------------------------------------------------------------------------- 11 | * 12 | * Pthreads-win32 - POSIX Threads Library for Win32 13 | * Copyright(C) 1998 John E. Bossom 14 | * Copyright(C) 1999,2005 Pthreads-win32 contributors 15 | * 16 | * Contact Email: rpj@callisto.canberra.edu.au 17 | * 18 | * The current list of contributors is contained 19 | * in the file CONTRIBUTORS included with the source 20 | * code distribution. The list can also be seen at the 21 | * following World Wide Web location: 22 | * http://sources.redhat.com/pthreads-win32/contributors.html 23 | * 24 | * This library is free software; you can redistribute it and/or 25 | * modify it under the terms of the GNU Lesser General Public 26 | * License as published by the Free Software Foundation; either 27 | * version 2 of the License, or (at your option) any later version. 28 | * 29 | * This library is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 32 | * Lesser General Public License for more details. 33 | * 34 | * You should have received a copy of the GNU Lesser General Public 35 | * License along with this library in the file COPYING.LIB; 36 | * if not, write to the Free Software Foundation, Inc., 37 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 38 | */ 39 | #if !defined( SEMAPHORE_H ) 40 | #define SEMAPHORE_H 41 | 42 | #undef PTW32_SEMAPHORE_LEVEL 43 | 44 | #if defined(_POSIX_SOURCE) 45 | #define PTW32_SEMAPHORE_LEVEL 0 46 | /* Early POSIX */ 47 | #endif 48 | 49 | #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 50 | #undef PTW32_SEMAPHORE_LEVEL 51 | #define PTW32_SEMAPHORE_LEVEL 1 52 | /* Include 1b, 1c and 1d */ 53 | #endif 54 | 55 | #if defined(INCLUDE_NP) 56 | #undef PTW32_SEMAPHORE_LEVEL 57 | #define PTW32_SEMAPHORE_LEVEL 2 58 | /* Include Non-Portable extensions */ 59 | #endif 60 | 61 | #define PTW32_SEMAPHORE_LEVEL_MAX 3 62 | 63 | #if !defined(PTW32_SEMAPHORE_LEVEL) 64 | #define PTW32_SEMAPHORE_LEVEL PTW32_SEMAPHORE_LEVEL_MAX 65 | /* Include everything */ 66 | #endif 67 | 68 | #if defined(__GNUC__) && ! defined (__declspec) 69 | # error Please upgrade your GNU compiler to one that supports __declspec. 70 | #endif 71 | 72 | /* 73 | * When building the library, you should define PTW32_BUILD so that 74 | * the variables/functions are exported correctly. When using the library, 75 | * do NOT define PTW32_BUILD, and then the variables/functions will 76 | * be imported correctly. 77 | */ 78 | #if !defined(PTW32_STATIC_LIB) 79 | # if defined(PTW32_BUILD) 80 | # define PTW32_DLLPORT __declspec (dllexport) 81 | # else 82 | # define PTW32_DLLPORT __declspec (dllimport) 83 | # endif 84 | #else 85 | # define PTW32_DLLPORT 86 | #endif 87 | 88 | /* 89 | * This is a duplicate of what is in the autoconf config.h, 90 | * which is only used when building the pthread-win32 libraries. 91 | */ 92 | 93 | #if !defined(PTW32_CONFIG_H) 94 | # if defined(WINCE) 95 | # define NEED_ERRNO 96 | # define NEED_SEM 97 | # endif 98 | # if defined(__MINGW64__) 99 | # define HAVE_STRUCT_TIMESPEC 100 | # define HAVE_MODE_T 101 | # elif defined(_UWIN) || defined(__MINGW32__) 102 | # define HAVE_MODE_T 103 | # endif 104 | #endif 105 | 106 | /* 107 | * 108 | */ 109 | 110 | #if PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX 111 | #if defined(NEED_ERRNO) 112 | #include "need_errno.h" 113 | #else 114 | #include 115 | #endif 116 | #endif /* PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX */ 117 | 118 | #define _POSIX_SEMAPHORES 119 | 120 | #if defined(__cplusplus) 121 | extern "C" 122 | { 123 | #endif /* __cplusplus */ 124 | 125 | #if !defined(HAVE_MODE_T) 126 | typedef unsigned int mode_t; 127 | #endif 128 | 129 | 130 | typedef struct sem_t_ * sem_t; 131 | 132 | PTW32_DLLPORT int __cdecl sem_init (sem_t * sem, 133 | int pshared, 134 | unsigned int value); 135 | 136 | PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem); 137 | 138 | PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem); 139 | 140 | PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem); 141 | 142 | PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem, 143 | const struct timespec * abstime); 144 | 145 | PTW32_DLLPORT int __cdecl sem_post (sem_t * sem); 146 | 147 | PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem, 148 | int count); 149 | 150 | PTW32_DLLPORT int __cdecl sem_open (const char * name, 151 | int oflag, 152 | mode_t mode, 153 | unsigned int value); 154 | 155 | PTW32_DLLPORT int __cdecl sem_close (sem_t * sem); 156 | 157 | PTW32_DLLPORT int __cdecl sem_unlink (const char * name); 158 | 159 | PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem, 160 | int * sval); 161 | 162 | #if defined(__cplusplus) 163 | } /* End of extern "C" */ 164 | #endif /* __cplusplus */ 165 | 166 | #undef PTW32_SEMAPHORE_LEVEL 167 | #undef PTW32_SEMAPHORE_LEVEL_MAX 168 | 169 | #endif /* !SEMAPHORE_H */ 170 | -------------------------------------------------------------------------------- /posix/lib/x64/libpthreadGC2.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/posix/lib/x64/libpthreadGC2.a -------------------------------------------------------------------------------- /posix/lib/x64/md5.sum: -------------------------------------------------------------------------------- 1 | 1889f7dfd51f3050a080fb5cc8ced295 libpthreadGC2.a 2 | d88796876eb48c988fa3a436a1fa973a pthreadVC2.lib 3 | -------------------------------------------------------------------------------- /posix/lib/x64/pthreadVC2.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/posix/lib/x64/pthreadVC2.lib -------------------------------------------------------------------------------- /posix/lib/x86/libpthreadGC2.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/posix/lib/x86/libpthreadGC2.a -------------------------------------------------------------------------------- /posix/lib/x86/md5.sum: -------------------------------------------------------------------------------- 1 | eb0a8beb556eb6a70bcf6e674d4a1238 libpthreadGC2.a 2 | 985a4cb93884dd7970618d8bcb07f86d libpthreadGCE2.a 3 | 800a283b5a30c41d1ec184ff5884123a pthreadVC2.lib 4 | ee5ab03e1583b8bf014b141ee4e4005d pthreadVCE2.lib 5 | c88e367a2d33bf2789148478e5ffe59a pthreadVSE2.lib 6 | -------------------------------------------------------------------------------- /posix/lib/x86/pthreadVC2.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/posix/lib/x86/pthreadVC2.lib -------------------------------------------------------------------------------- /posix/lib/x86/pthreadVCE2.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/posix/lib/x86/pthreadVCE2.lib -------------------------------------------------------------------------------- /posix/lib/x86/pthreadVSE2.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/posix/lib/x86/pthreadVSE2.lib -------------------------------------------------------------------------------- /rsp_tcp/IPAddress.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | ** RSP_tcp - TCP/IP I/Q Data Server for the sdrplay RSP2 3 | ** Copyright (C) 2017 Clem Schmidt, softsyst GmbH, http://www.softsyst.com 4 | ** 5 | ** This program is free software; you can redistribute it and/or modify 6 | ** it under the terms of the GNU General Public License as published by 7 | ** the Free Software Foundation; either version 2 of the License, or 8 | ** (at your option) any later version. 9 | ** 10 | ** This program is distributed in the hope that it will be useful, 11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ** GNU General Public License for more details. 14 | ** 15 | ** You should have received a copy of the GNU General Public License 16 | ** along with this program; if not, write to the Free Software 17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | ** 19 | **/ 20 | 21 | #include "IPAddress.h" 22 | #include 23 | using namespace std; 24 | 25 | IPAddress::IPAddress(const string& s) 26 | { 27 | try 28 | { 29 | parse(s); 30 | sIPAddress = s; 31 | valid = true; 32 | } 33 | catch (const std::exception& e) 34 | { 35 | cout << e.what() << endl << endl; 36 | b1 = b2 = b3 = 0; 37 | valid = false; 38 | } 39 | } 40 | IPAddress::IPAddress(BYTE a1, BYTE a2, BYTE a3, BYTE a4) 41 | { 42 | valid = false; 43 | if (checkRange(a1) && checkRange(a2) && checkRange(a3) && checkRange(a4)) 44 | { 45 | b1 = a1; b2 = a2; b3 = a3; b4 = a4; 46 | sIPAddress = to_string(b1) + "." + to_string(b2) + "." + to_string(b3) + "." + to_string(b4); 47 | valid = true; 48 | } 49 | } 50 | 51 | IPAddress::IPAddress(const IPAddress& src) 52 | { 53 | sIPAddress = src.sIPAddress; 54 | b1 = src.b1; b2 = src.b2; b3 = src.b3; b4 = src.b4; 55 | } 56 | 57 | bool IPAddress::operator==(const IPAddress& other) const 58 | { 59 | if (this == &other) 60 | return true; 61 | if (this->b1 == other.b1 && this->b2 == other.b2 && this->b3 == other.b3 && this->b4 == other.b4 && 62 | this->sIPAddress == other.sIPAddress) 63 | return true; 64 | return false; 65 | } 66 | 67 | IPAddress& IPAddress::operator= (const IPAddress& other) 68 | { 69 | if ( *this == other) 70 | return *this; 71 | sIPAddress = other.sIPAddress; 72 | b1 = other.b1; b2 = other.b2; b3 = other.b3; b4 = other.b4; 73 | return *this; 74 | } 75 | 76 | bool IPAddress::checkRange(int val) const 77 | { 78 | return common::checkRange(val, 0, 255); 79 | } 80 | 81 | void IPAddress::parse(const string& s) 82 | { 83 | { 84 | vector parts = common::split(s, '.'); 85 | if (parts.size() != 4) 86 | throw rsptcpException("IPAddress parsing error."); 87 | 88 | int val = stoi(parts[0]); 89 | if (checkRange(val)) 90 | b1 = (unsigned char)val; 91 | else 92 | throw rsptcpException("IPAddress out of range error."); 93 | 94 | val = stoi(parts[1]); 95 | if (checkRange(val)) 96 | b2 = (unsigned char)val; 97 | else 98 | throw rsptcpException("IPAddress out of range error."); 99 | 100 | val = stoi(parts[2]); 101 | if (checkRange(val)) 102 | b3 = (unsigned char)val; 103 | else 104 | throw rsptcpException("IPAddress out of range error."); 105 | 106 | val = stoi(parts[3]); 107 | if (checkRange(val)) 108 | b4 = (unsigned char)val; 109 | else 110 | throw rsptcpException("IPAddress range error."); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /rsp_tcp/IPAddress.h: -------------------------------------------------------------------------------- 1 | /** 2 | ** RSP_tcp - TCP/IP I/Q Data Server for the sdrplay RSP2 3 | ** Copyright (C) 2017 Clem Schmidt, softsyst GmbH, http://www.softsyst.com 4 | ** 5 | ** This program is free software; you can redistribute it and/or modify 6 | ** it under the terms of the GNU General Public License as published by 7 | ** the Free Software Foundation; either version 2 of the License, or 8 | ** (at your option) any later version. 9 | ** 10 | ** This program is distributed in the hope that it will be useful, 11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ** GNU General Public License for more details. 14 | ** 15 | ** You should have received a copy of the GNU General Public License 16 | ** along with this program; if not, write to the Free Software 17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | ** 19 | **/ 20 | 21 | #pragma once 22 | #include 23 | #include "common.h" 24 | 25 | struct IPAddress 26 | { 27 | std::string sIPAddress; 28 | unsigned char b1, b2, b3, b4; 29 | bool valid; 30 | 31 | IPAddress(const std::string& s); 32 | IPAddress(BYTE a1, BYTE a2, BYTE a3, BYTE a4); 33 | IPAddress(const IPAddress& src); 34 | IPAddress& operator= (const IPAddress& other); 35 | bool operator==(const IPAddress& other) const; 36 | bool checkRange(int val) const; 37 | void parse(const std::string& s); 38 | }; 39 | -------------------------------------------------------------------------------- /rsp_tcp/MeasTimeDiff.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include ".\meastimediff.h" 5 | 6 | /////////////////////////////////////////////////////////////////////////////// 7 | void CMeasTimeDiff::formattedTimeOutput(const std::string& s, const double& tim) 8 | { 9 | std::cout << s << std::setprecision(5) << tim << std::endl; 10 | } 11 | /////////////////////////////////////////////////////////////////////////////// 12 | //factor == 1: Time in seconds 13 | //factor == 1e9 Time in nanoseconds 14 | //factor == 1e3 Time in milliseconds 15 | // etc. 16 | double CMeasTimeDiff::calcTimeDiff( 17 | const LARGE_INTEGER& count2, 18 | const LARGE_INTEGER& count1, const double& factor) 19 | { 20 | LARGE_INTEGER frequency; 21 | BOOL b = QueryPerformanceFrequency(&frequency); 22 | if (b == FALSE) //then perf. counting not supported 23 | return 0.0; 24 | 25 | double time_in_unit = 0.0; 26 | double oneCount_perTime = 1/(double)frequency.QuadPart * factor; 27 | 28 | LONGLONG delta = count2.QuadPart - count1.QuadPart; 29 | time_in_unit = (double)delta * oneCount_perTime; 30 | 31 | return time_in_unit; 32 | } 33 | /////////////////////////////////////////////////////////////////////////////// 34 | double CMeasTimeDiff::calcTimeDiff_in_ms( 35 | const LARGE_INTEGER& count2, 36 | const LARGE_INTEGER& count1) 37 | { 38 | return calcTimeDiff (count2, count1, 1e3); 39 | } 40 | /////////////////////////////////////////////////////////////////////////////// 41 | double CMeasTimeDiff::calcTimeDiff_in_us( 42 | const LARGE_INTEGER& count2, 43 | const LARGE_INTEGER& count1) 44 | { 45 | return calcTimeDiff (count2, count1, 1e6); 46 | } 47 | /////////////////////////////////////////////////////////////////////////////// 48 | double CMeasTimeDiff::calcTimeDiff_in_ns( 49 | const LARGE_INTEGER& count2, 50 | const LARGE_INTEGER& count1) 51 | { 52 | return calcTimeDiff (count2, count1, 1e9); 53 | } 54 | 55 | -------------------------------------------------------------------------------- /rsp_tcp/MeasTimeDiff.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class CMeasTimeDiff 5 | { 6 | public: 7 | static double calcTimeDiff( 8 | const LARGE_INTEGER& count2, 9 | const LARGE_INTEGER& count1, const double& factor); 10 | static double calcTimeDiff_in_ms( 11 | const LARGE_INTEGER& count2, 12 | const LARGE_INTEGER& count1); 13 | static double calcTimeDiff_in_us( 14 | const LARGE_INTEGER& count2, 15 | const LARGE_INTEGER& count1); 16 | static double calcTimeDiff_in_ns( 17 | const LARGE_INTEGER& count2, 18 | const LARGE_INTEGER& count1); 19 | static void formattedTimeOutput(const std::string& s, const double& tim); 20 | }; 21 | -------------------------------------------------------------------------------- /rsp_tcp/common.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | ** RSP_tcp - TCP/IP I/Q Data Server for the sdrplay RSP2 3 | ** Copyright (C) 2017 Clem Schmidt, softsyst GmbH, http://www.softsyst.com 4 | ** 5 | ** This program is free software; you can redistribute it and/or modify 6 | ** it under the terms of the GNU General Public License as published by 7 | ** the Free Software Foundation; either version 2 of the License, or 8 | ** (at your option) any later version. 9 | ** 10 | ** This program is distributed in the hope that it will be useful, 11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ** GNU General Public License for more details. 14 | ** 15 | ** You should have received a copy of the GNU General Public License 16 | ** along with this program; if not, write to the Free Software 17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | ** 19 | **/ 20 | 21 | #pragma once 22 | #include "common.h" 23 | 24 | #ifdef _WIN32 25 | int common::gettimeofday(struct timeval *tv, void* ignored) 26 | { 27 | FILETIME ft; 28 | unsigned __int64 tmp = 0; 29 | if (NULL != tv) { 30 | GetSystemTimeAsFileTime(&ft); 31 | tmp |= ft.dwHighDateTime; 32 | tmp <<= 32; 33 | tmp |= ft.dwLowDateTime; 34 | tmp /= 10; 35 | #ifdef _MSC_VER 36 | tmp -= 11644473600000000Ui64; 37 | #else 38 | tmp -= 11644473600000000ULL; 39 | #endif 40 | tv->tv_sec = (long)(tmp / 1000000UL); 41 | tv->tv_usec = (long)(tmp % 1000000UL); 42 | } 43 | return 0; 44 | } 45 | #endif 46 | 47 | template 48 | void common::split(const std::string &s, char delim, Out result) { 49 | std::stringstream ss(s); 50 | std::string item; 51 | while (std::getline(ss, item, delim)) { 52 | *(result++) = item; 53 | } 54 | } 55 | 56 | std::vector common::split(const std::string &s, char delim) { 57 | std::vector elems; 58 | split(s, delim, std::back_inserter(elems)); 59 | return elems; 60 | } 61 | 62 | bool common::checkRange(int val, int minval, int maxval) 63 | { 64 | if (val >= minval && val <= maxval) 65 | return true; 66 | return false; 67 | } 68 | 69 | bool common::isLittleEndian() 70 | { 71 | if (htonl(99) == 99) 72 | return false; 73 | return true; 74 | } 75 | 76 | timespec common::getRelativeTimeoutValue(int relativeTimeoutSec) 77 | { 78 | struct timeval now; 79 | gettimeofday(&now, NULL); 80 | struct timespec timeout;//1 second 81 | timeout.tv_sec = now.tv_sec + relativeTimeoutSec; 82 | timeout.tv_nsec = now.tv_usec * 1000; 83 | return timeout; 84 | } 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /rsp_tcp/common.h: -------------------------------------------------------------------------------- 1 | /** 2 | ** RSP_tcp - TCP/IP I/Q Data Server for the sdrplay RSP2 3 | ** Copyright (C) 2017 Clem Schmidt, softsyst GmbH, http://www.softsyst.com 4 | ** 5 | ** This program is free software; you can redistribute it and/or modify 6 | ** it under the terms of the GNU General Public License as published by 7 | ** the Free Software Foundation; either version 2 of the License, or 8 | ** (at your option) any later version. 9 | ** 10 | ** This program is distributed in the hope that it will be useful, 11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ** GNU General Public License for more details. 14 | ** 15 | ** You should have received a copy of the GNU General Public License 16 | ** along with this program; if not, write to the Free Software 17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | ** 19 | **/ 20 | 21 | #pragma once 22 | #include 23 | #include 24 | #include 25 | #include 26 | #ifndef _WIN32 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #else 36 | #include 37 | //#include 38 | #include 39 | #endif 40 | typedef unsigned char BYTE; 41 | 42 | #ifdef _WIN32 43 | #pragma comment(lib, "ws2_32.lib") 44 | 45 | typedef int socklen_t; 46 | 47 | #else 48 | #define closesocket close 49 | #define SOCKADDR struct sockaddr 50 | #define SOCKET int 51 | #define INVALID_SOCKET ((SOCKET)(~0)) 52 | #define SOCKET_ERROR -1 53 | #endif 54 | 55 | 56 | class common 57 | { 58 | private: 59 | template 60 | static void split(const std::string &s, char delim, Out result); 61 | public: 62 | static std::vector split(const std::string &s, char delim); 63 | static bool checkRange(int val, int minval, int maxval); 64 | 65 | static bool isLittleEndian(); 66 | static timespec getRelativeTimeoutValue(int relativeTimeoutSec); 67 | #ifdef _WIN32 68 | static int gettimeofday(struct timeval *tv, void* ignored); 69 | #endif 70 | 71 | static std::string getSocketErrorString() 72 | { 73 | #ifdef _WIN32 74 | int err = WSAGetLastError(); 75 | return std::to_string(err); 76 | #else 77 | return std::to_string(errno); 78 | #endif 79 | } 80 | }; 81 | 82 | class msg_exception : public std::exception 83 | { 84 | public: 85 | msg_exception(std::string const &message) : msg_(message) { } 86 | virtual char const *what() const noexcept { return msg_.c_str(); } 87 | 88 | private: 89 | std::string msg_; 90 | }; 91 | 92 | class rsptcpException : public msg_exception 93 | { 94 | public : 95 | rsptcpException(const char* msg) : msg_exception(std::string(msg)) {} 96 | }; 97 | 98 | -------------------------------------------------------------------------------- /rsp_tcp/controlThread.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | ** RSP2_tcp - TCP/IP I/Q Data Server for the sdrplay RSP2 3 | ** Copyright (C) 2017 Clem Schmidt, softsyst GmbH, http://www.softsyst.com 4 | ** 5 | ** This program is free software; you can redistribute it and/or modify 6 | ** it under the terms of the GNU General Public License as published by 7 | ** the Free Software Foundation; either version 2 of the License, or 8 | ** (at your option) any later version. 9 | ** 10 | ** This program is distributed in the hope that it will be useful, 11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ** GNU General Public License for more details. 14 | ** 15 | ** You should have received a copy of the GNU General Public License 16 | ** along with this program; if not, write to the Free Software 17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | ** 19 | **/ 20 | 21 | #define _WINSOCK_DEPRECATED_NO_WARNINGS 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #ifndef _WIN32 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #else 38 | #include 39 | //#include "getopt/getopt.h" 40 | #endif 41 | 42 | #ifdef NEED_PTHREADS_WORKARROUND 43 | #define HAVE_STRUCT_TIMESPEC 44 | #endif 45 | //#include 46 | 47 | #include "mir_sdr_device.h" 48 | 49 | #ifdef _WIN32 50 | #pragma comment(lib, "ws2_32.lib") 51 | 52 | typedef int socklen_t; 53 | 54 | #else 55 | #define closesocket close 56 | #define SOCKADDR struct sockaddr 57 | #define SOCKET int 58 | #define SOCKET_ERROR -1 59 | #endif 60 | 61 | #define MAX_LEN 256 62 | #define TX_BUF_LEN (32) //tbd 63 | 64 | ctrl_thread_data_t ctrl_thread_data; 65 | 66 | void *ctrl_thread_fn(void *arg) 67 | { 68 | unsigned char reg_values[MAX_LEN]; 69 | unsigned char txbuf[TX_BUF_LEN]; 70 | int r = 1; 71 | struct timeval tv = { 1,0 }; 72 | struct linger ling = { 1,0 }; 73 | SOCKET listensocket; 74 | SOCKET controlSocket; 75 | int haveControlSocket = 0; 76 | struct sockaddr_in local, remote; 77 | socklen_t rlen; 78 | 79 | int len, result, total_gain=123; 80 | fd_set connfds; 81 | fd_set writefds; 82 | int bytesleft, bytessent, index; 83 | int old_gain = 0; 84 | 85 | ctrl_thread_data_t *data = (ctrl_thread_data_t *)arg; 86 | 87 | mir_sdr_device *dev = (mir_sdr_device *)data->dev; 88 | int port = data->port; 89 | int wait = data->wait; 90 | const char *addr = data->addr; 91 | bool* do_exit = data->pDoExit; 92 | u_long blockmode = 1; 93 | int retval; 94 | 95 | memset(reg_values, 0, MAX_LEN); 96 | 97 | memset(&local, 0, sizeof(local)); 98 | local.sin_family = AF_INET; 99 | local.sin_port = htons(port); 100 | local.sin_addr.s_addr = inet_addr(addr); 101 | 102 | listensocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 103 | 104 | setsockopt(listensocket, SOL_SOCKET, SO_REUSEADDR, (char *)&r, sizeof(int)); 105 | setsockopt(listensocket, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling)); 106 | retval = bind(listensocket, (struct sockaddr *)&local, sizeof(local)); 107 | if (retval == SOCKET_ERROR) 108 | goto close; 109 | #ifdef _WIN32 110 | ioctlsocket(listensocket, FIONBIO, &blockmode); 111 | #else 112 | r = fcntl(listensocket, F_GETFL, 0); 113 | r = fcntl(listensocket, F_SETFL, r | O_NONBLOCK); 114 | #endif 115 | 116 | while (1) { 117 | printf("\n\nlistening on Control port %d...\n", port); 118 | retval = listen(listensocket, 1); 119 | if (retval == SOCKET_ERROR) 120 | goto close; 121 | while (1) { 122 | FD_ZERO(&connfds); 123 | FD_SET(listensocket, &connfds); 124 | tv.tv_sec = 1; 125 | tv.tv_usec = 0; 126 | r = select(listensocket + 1, &connfds, NULL, NULL, &tv); 127 | if (*do_exit) { 128 | goto close; 129 | } 130 | else if (r) { 131 | rlen = sizeof(remote); 132 | controlSocket = accept(listensocket, (struct sockaddr *)&remote, &rlen); 133 | haveControlSocket = 1; 134 | break; 135 | } 136 | result = 0;// rtlsdr_get_tuner_i2c_register(dev, reg_values, &len, &total_gain); 137 | total_gain = ((total_gain + 5) / 10)%256; 138 | if (old_gain != total_gain) 139 | { 140 | printf("\ngain = %2d dB\r", total_gain); 141 | old_gain = total_gain; 142 | } 143 | } 144 | 145 | setsockopt(controlSocket, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling)); 146 | 147 | printf("\nControl client accepted!\n"); 148 | //usleep(5000000); 149 | 150 | while (1) { 151 | 152 | 153 | /* @TODO: check if something else has to be transmitted */ 154 | if (false) 155 | goto sleep; 156 | 157 | len = 0; 158 | total_gain = 123; 159 | result = 0; 160 | mir_sdr_GainValuesT gainVals; 161 | mir_sdr_ErrT err = mir_sdr_GetCurrentGain(&gainVals); 162 | total_gain = (int)(gainVals.curr * 10.0f); 163 | //result = rtlsdr_get_tuner_i2c_register(dev, reg_values, &len, &total_gain); 164 | memset(txbuf, 0, TX_BUF_LEN); 165 | if (result) 166 | goto sleep; 167 | 168 | //Big Endian / Network Byte Order 169 | txbuf[0] = 0;// REPORT_I2C_REGS; 170 | txbuf[1] = ((len + 2) >> 8) & 0xff; 171 | txbuf[2] = (len + 2) & 0xff; 172 | txbuf[3] = (total_gain >> 8) & 0xff; 173 | txbuf[4] = total_gain & 0xff; 174 | /* now the message contents */ 175 | //memcpy(&txbuf[5], reg_values, len); 176 | len += 5; 177 | 178 | /* now start (possibly blocking) transmission */ 179 | bytessent = 0; 180 | bytesleft = len; 181 | index = 0; 182 | while (bytesleft > 0) { 183 | FD_ZERO(&writefds); 184 | FD_SET(controlSocket, &writefds); 185 | tv.tv_sec = 1; 186 | tv.tv_usec = 0; 187 | r = select(controlSocket + 1, NULL, &writefds, NULL, &tv); 188 | if (r) { 189 | bytessent = send(controlSocket, (const char*)&txbuf[index], bytesleft, 0); 190 | bytesleft -= bytessent; 191 | index += bytessent; 192 | } 193 | if (bytessent == SOCKET_ERROR || *do_exit) { 194 | goto close; 195 | } 196 | } 197 | sleep: 198 | usleep(wait); 199 | } 200 | close: 201 | if (haveControlSocket) 202 | closesocket(controlSocket); 203 | if (*do_exit) 204 | { 205 | closesocket(listensocket); 206 | printf("Control Thread terminates\n"); 207 | break; 208 | } 209 | } 210 | return 0; 211 | } 212 | -------------------------------------------------------------------------------- /rsp_tcp/controlThread.h: -------------------------------------------------------------------------------- 1 | /** 2 | ** RSP_tcp - TCP/IP I/Q Data Server for the sdrplay RSP2 3 | ** Copyright (C) 2017 Clem Schmidt, softsyst GmbH, http://www.softsyst.com 4 | ** 5 | ** This program is free software; you can redistribute it and/or modify 6 | ** it under the terms of the GNU General Public License as published by 7 | ** the Free Software Foundation; either version 2 of the License, or 8 | ** (at your option) any later version. 9 | ** 10 | ** This program is distributed in the hope that it will be useful, 11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ** GNU General Public License for more details. 14 | ** 15 | ** You should have received a copy of the GNU General Public License 16 | ** along with this program; if not, write to the Free Software 17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | ** 19 | **/ 20 | 21 | #pragma once 22 | #include "devices.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | typedef struct 29 | { 30 | mir_sdr_device *dev; 31 | int port; 32 | int wait; 33 | const char *addr; 34 | bool* pDoExit; 35 | } 36 | ctrl_thread_data_t; 37 | void *ctrl_thread_fn(void *arg); 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | -------------------------------------------------------------------------------- /rsp_tcp/devices.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | ** RSP_tcp - TCP/IP I/Q Data Server for the sdrplay RSP2 3 | ** Copyright (C) 2017 Clem Schmidt, softsyst GmbH, http://www.softsyst.com 4 | ** 5 | ** This program is free software; you can redistribute it and/or modify 6 | ** it under the terms of the GNU General Public License as published by 7 | ** the Free Software Foundation; either version 2 of the License, or 8 | ** (at your option) any later version. 9 | ** 10 | ** This program is distributed in the hope that it will be useful, 11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ** GNU General Public License for more details. 14 | ** 15 | ** You should have received a copy of the GNU General Public License 16 | ** along with this program; if not, write to the Free Software 17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | ** 19 | **/ 20 | 21 | #include 22 | #include 23 | #include 24 | #include "devices.h" 25 | #ifndef _WIN32 26 | #include 27 | #endif 28 | 29 | using namespace std; 30 | 31 | mir_sdr_device* devices::selectDevice() 32 | { 33 | mir_sdr_ErrT err; 34 | if (mirDevices.size() == 0) 35 | { 36 | cout << "No device available. Cannot continue.\n"; 37 | return 0; 38 | } 39 | if (!getDevices()) 40 | { 41 | cout << "getDevices failed. Cannot continue.\n"; 42 | return 0; 43 | } 44 | //mir_sdr_device* pd = findFreeDevice(); 45 | //if (pd == 0) 46 | // cout << "No free device available.\n"; 47 | mir_sdr_device* pd = findRequestedDevice(pargs->requestedDeviceIndex); 48 | if (pd == 0) 49 | { 50 | cout << "Requested Device " << pargs->requestedDeviceIndex << " not available.\n"; 51 | return 0; 52 | } 53 | pd->VERBOSE = pargs->verbose == 1; 54 | currentDevice = pd; 55 | err = mir_sdr_SetDeviceIdx(pd->DeviceIndex); 56 | cout << "mir_sdr_SetDeviceIdx " << pd->DeviceIndex << " returned with: " << err << endl; 57 | 58 | if (err == mir_sdr_Success) 59 | { 60 | cout << "Device Index " << pd->DeviceIndex << " successfully set" << endl; 61 | pd->init(pargs); 62 | //pd->start(clientSocket); // creates the receive and stream thread 63 | } 64 | else 65 | { 66 | cout << "Cannot select Device " << pargs->requestedDeviceIndex << " \n"; 67 | return 0; 68 | } 69 | return pd; 70 | } 71 | 72 | 73 | // Loops endless until Stop 74 | void devices::Start(rsp_cmdLineArgs* pargs) 75 | { 76 | this->pargs = pargs; 77 | try 78 | { 79 | listenerAddress = pargs->Address; 80 | listenerPort = pargs->Port; 81 | initListener(); 82 | 83 | //mir_sdr_device* pd = selectDevice(); 84 | //if (pd == 0) 85 | // return; 86 | 87 | //listenerCtrlAddress = listenerAddress; 88 | //listenerCtrlPort = listenerPort+1; 89 | 90 | doListen(); 91 | 92 | if (getNumberOfDevices() < 1) 93 | throw msg_exception("No sdrplay devices present."); 94 | } 95 | catch (const std::exception& e) 96 | { 97 | cout << "Cannot start listener: " << e.what() << endl; 98 | } 99 | } 100 | 101 | 102 | // The stop command for the server, not the device 103 | // Intent is to stop all devices and release everything 104 | void devices::Stop() 105 | { 106 | 107 | map::iterator it; 108 | 109 | for (it = mirDevices.begin(); it != mirDevices.end(); it++) 110 | { 111 | mir_sdr_device* pd = it->second; 112 | //pd->stop(); 113 | delete pd; 114 | } 115 | closesocket(listenSocket); 116 | listenSocket = INVALID_SOCKET; 117 | } 118 | 119 | mir_sdr_device* devices::findFreeDevice() 120 | { 121 | map::iterator it; 122 | 123 | for (it = mirDevices.begin(); it != mirDevices.end(); it++) 124 | { 125 | mir_sdr_device* pd = it->second; 126 | if (!pd->started && pd->devAvail) 127 | return pd; 128 | } 129 | return 0; 130 | } 131 | 132 | mir_sdr_device* devices::findRequestedDevice(int rqIdx) 133 | { 134 | map::iterator it; 135 | 136 | for (it = mirDevices.begin(); it != mirDevices.end(); it++) 137 | { 138 | mir_sdr_device* pd = it->second; 139 | if (!pd->started && pd->devAvail && pd->DeviceIndex == rqIdx) 140 | return pd; 141 | } 142 | return 0; 143 | } 144 | 145 | void devices::setDeviceIdle(int rqIdx) 146 | { 147 | map::iterator it; 148 | 149 | for (it = mirDevices.begin(); it != mirDevices.end(); it++) 150 | { 151 | mir_sdr_device* pd = it->second; 152 | if (pd->DeviceIndex == rqIdx) 153 | pd->started = false; 154 | } 155 | } 156 | 157 | 158 | 159 | void devices::doListen() 160 | { 161 | mir_sdr_ErrT err; 162 | try 163 | { 164 | int maxConnections = 1; 165 | SOCKET sock = listenSocket; 166 | int res = listen(sock, maxConnections); 167 | if (res == SOCKET_ERROR) 168 | throw msg_exception(common::getSocketErrorString()); 169 | 170 | while (sock != INVALID_SOCKET) 171 | { 172 | currentDevice = 0; 173 | 174 | mir_sdr_device* pd = selectDevice(); 175 | if (pd == 0) 176 | return; 177 | 178 | // create the control thread and its socket communication 179 | pd->createCtrlThread(listenerAddress.sIPAddress.c_str(), listenerPort+1 ); 180 | 181 | cout << "Listening to " << listenerAddress.sIPAddress << ":" << to_string(listenerPort) << endl; 182 | socklen_t rlen = sizeof(remote); 183 | clientSocket = accept(sock, (struct sockaddr *)&remote, &rlen); 184 | cout << "Client Accepted!\n" << endl; 185 | 186 | pd->start(clientSocket); // creates the receive and stream thread 187 | 188 | void* status; 189 | pthread_join(*pd->thrdRx, &status); 190 | cout << endl << "++++ Rx thread terminated ++++" << endl; 191 | delete pd->thrdRx; 192 | pd->thrdRx = 0; 193 | pd->stop(); 194 | 195 | pthread_join(*pd->thrdCtrl, &status); 196 | cout << endl << "++++ Ctrl thread terminated ++++" << endl; 197 | delete pd->thrdCtrl; 198 | pd->thrdCtrl = 0; 199 | 200 | closesocket(clientSocket); 201 | pd->remoteClient = INVALID_SOCKET; 202 | cout << "Socket closed\n\n"; 203 | setDeviceIdle(pd->DeviceIndex); 204 | 205 | } 206 | } 207 | catch (exception& e) 208 | { 209 | cout << "Error starting listener: " << e.what(); 210 | } 211 | } 212 | 213 | void devices::initListener() 214 | { 215 | memset(&local, 0, sizeof(local)); 216 | local.sin_family = AF_INET; 217 | local.sin_port = htons(listenerPort); 218 | local.sin_addr.s_addr = inet_addr(listenerAddress.sIPAddress.c_str()); 219 | 220 | listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 221 | if (listenSocket == INVALID_SOCKET) 222 | throw msg_exception("INVALID_SOCKET"); 223 | int r = 1; 224 | struct linger ling = { 1,0 }; 225 | 226 | int res = setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&r, sizeof(int)); 227 | if (res == SOCKET_ERROR) 228 | throw msg_exception(common::getSocketErrorString().c_str()); 229 | 230 | res = setsockopt(listenSocket, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling)); 231 | if (res == SOCKET_ERROR) 232 | throw msg_exception(common::getSocketErrorString().c_str()); 233 | 234 | res = ::bind(listenSocket, (struct sockaddr *)&local, sizeof(local)); 235 | if (res == SOCKET_ERROR) 236 | throw msg_exception(common::getSocketErrorString().c_str()); 237 | } 238 | 239 | /// 240 | /// Collect all sdrplay devices 241 | /// 242 | /// 243 | bool devices::getDevices() 244 | { 245 | const int c_maxDevices = 5; 246 | mir_sdr_DeviceT mydevices[c_maxDevices] ; 247 | try 248 | { 249 | unsigned int numDevs = 0; 250 | { 251 | mir_sdr_ErrT err; 252 | err = mir_sdr_GetDevices(mydevices, &numDevs, c_maxDevices); 253 | if (numDevs == 0) 254 | return false; 255 | 256 | int ierr = (int)err; 257 | string error = "mir_sdr_device failed with error :" + to_string(ierr); 258 | cout << "mir_sdr_GetDevices returned with: " << err << endl; 259 | for (int i = 0; i < (int)numDevs; i++) 260 | { 261 | if (err != mir_sdr_Success) 262 | throw msg_exception(error.c_str()); 263 | 264 | mir_sdr_device* pd = new mir_sdr_device(); 265 | if ((mydevices[i].hwVer < 1 || mydevices[i].hwVer > 3) && mydevices[i].hwVer != 255 ) 266 | { 267 | printf("Unknown Hardware version %d .\n", mydevices[i].hwVer); 268 | continue; 269 | } 270 | pd->devAvail = mydevices[i].devAvail == 1; 271 | pd->hwVer = mydevices[i].hwVer; 272 | pd->serno = mydevices[i].SerNo; 273 | pd->DevNm = mydevices[i].DevNm; 274 | pd->DeviceIndex = (unsigned int)i; 275 | if (mirDevices.count(pd->serno) == 0) 276 | mirDevices.insert (pair(pd->serno, pd)); 277 | else 278 | { 279 | mirDevices[pd->serno]->devAvail = pd->devAvail; 280 | mirDevices[pd->serno]->hwVer = pd->hwVer; 281 | mirDevices[pd->serno]->DevNm = pd->DevNm; 282 | mirDevices[pd->serno]->DeviceIndex = pd->DeviceIndex; 283 | delete pd; 284 | } 285 | } 286 | } 287 | } 288 | catch (exception& e) 289 | { 290 | cout << "Error reading devices: " << e.what() << endl; 291 | return false; 292 | } 293 | return true; 294 | } 295 | -------------------------------------------------------------------------------- /rsp_tcp/devices.h: -------------------------------------------------------------------------------- 1 | /** 2 | ** RSP_tcp - TCP/IP I/Q Data Server for the sdrplay RSP2 3 | ** Copyright (C) 2017 Clem Schmidt, softsyst GmbH, http://www.softsyst.com 4 | ** 5 | ** This program is free software; you can redistribute it and/or modify 6 | ** it under the terms of the GNU General Public License as published by 7 | ** the Free Software Foundation; either version 2 of the License, or 8 | ** (at your option) any later version. 9 | ** 10 | ** This program is distributed in the hope that it will be useful, 11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ** GNU General Public License for more details. 14 | ** 15 | ** You should have received a copy of the GNU General Public License 16 | ** along with this program; if not, write to the Free Software 17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | ** 19 | **/ 20 | 21 | #pragma once 22 | #ifdef _WIN32 23 | #pragma warning(disable:4996) 24 | #endif 25 | #include 26 | #include "rsp_tcp.h" 27 | #include "common.h" 28 | #include "IPAddress.h" 29 | #include "mir_sdr_device.h" 30 | #include "mir_sdr.h" 31 | #include "rsp_cmdLineArgs.h" 32 | 33 | class devices 34 | { 35 | 36 | // Singleton pattern 37 | private: 38 | devices() {} 39 | devices(devices const&); // Don't Implement 40 | void operator=(devices const&); // Don't implement 41 | 42 | public: 43 | static devices& instance() 44 | { 45 | static devices instance; // Guaranteed to be destroyed. 46 | // Instantiated on first use. 47 | return instance; 48 | } 49 | //devices(devices const&) = delete; 50 | //void operator=(devices const&) = delete; 51 | mir_sdr_device* findFreeDevice(); 52 | mir_sdr_device* findRequestedDevice(int rqIdx); 53 | void setDeviceIdle(int rqIdx); 54 | void Start(rsp_cmdLineArgs* pargs); 55 | void Stop(); 56 | void doListen(); 57 | bool getDevices() ; 58 | int getNumberOfDevices() const { return mirDevices.size(); } 59 | mir_sdr_device* selectDevice(); 60 | 61 | private: 62 | void initListener(); 63 | 64 | mir_sdr_device* currentDevice; 65 | SOCKET clientSocket = INVALID_SOCKET; 66 | SOCKET listenSocket = INVALID_SOCKET; 67 | sockaddr_in local; 68 | sockaddr_in remote; 69 | struct addrinfo *result = NULL; 70 | //struct addrinfo hints; 71 | 72 | // command line arguments 73 | rsp_cmdLineArgs* pargs; 74 | 75 | // default values, may be overridden by command line arguments 76 | IPAddress listenerAddress = IPAddress(0,0,0,0); 77 | int listenerPort = 7890; 78 | 79 | IPAddress listenerCtrlAddress = IPAddress(0,0,0,0); 80 | int listenerCtrlPort; 81 | 82 | public: 83 | 84 | /// 85 | /// The list of all RSP2 devices 86 | /// Key: Serial Number, Value: Object 87 | /// 88 | map mirDevices; 89 | }; 90 | 91 | -------------------------------------------------------------------------------- /rsp_tcp/getopt/getopt.h: -------------------------------------------------------------------------------- 1 | /* Declarations for getopt. 2 | Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | 5 | The GNU C Library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | The GNU C Library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with the GNU C Library; if not, write to the Free 17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 | 02111-1307 USA. */ 19 | 20 | #ifndef _GETOPT_H 21 | 22 | #ifndef __need_getopt 23 | # define _GETOPT_H 1 24 | #endif 25 | 26 | /* If __GNU_LIBRARY__ is not already defined, either we are being used 27 | standalone, or this is the first header included in the source file. 28 | If we are being used with glibc, we need to include , but 29 | that does not exist if we are standalone. So: if __GNU_LIBRARY__ is 30 | not defined, include , which will pull in for us 31 | if it's from glibc. (Why ctype.h? It's guaranteed to exist and it 32 | doesn't flood the namespace with stuff the way some other headers do.) */ 33 | #if !defined __GNU_LIBRARY__ 34 | # include 35 | #endif 36 | 37 | #ifdef __cplusplus 38 | extern "C" { 39 | #endif 40 | 41 | /* For communication from `getopt' to the caller. 42 | When `getopt' finds an option that takes an argument, 43 | the argument value is returned here. 44 | Also, when `ordering' is RETURN_IN_ORDER, 45 | each non-option ARGV-element is returned here. */ 46 | 47 | extern char *optarg; 48 | 49 | /* Index in ARGV of the next element to be scanned. 50 | This is used for communication to and from the caller 51 | and for communication between successive calls to `getopt'. 52 | 53 | On entry to `getopt', zero means this is the first call; initialize. 54 | 55 | When `getopt' returns -1, this is the index of the first of the 56 | non-option elements that the caller should itself scan. 57 | 58 | Otherwise, `optind' communicates from one call to the next 59 | how much of ARGV has been scanned so far. */ 60 | 61 | extern int optind; 62 | 63 | /* Callers store zero here to inhibit the error message `getopt' prints 64 | for unrecognized options. */ 65 | 66 | extern int opterr; 67 | 68 | /* Set to an option character which was unrecognized. */ 69 | 70 | extern int optopt; 71 | 72 | #ifndef __need_getopt 73 | /* Describe the long-named options requested by the application. 74 | The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector 75 | of `struct option' terminated by an element containing a name which is 76 | zero. 77 | 78 | The field `has_arg' is: 79 | no_argument (or 0) if the option does not take an argument, 80 | required_argument (or 1) if the option requires an argument, 81 | optional_argument (or 2) if the option takes an optional argument. 82 | 83 | If the field `flag' is not NULL, it points to a variable that is set 84 | to the value given in the field `val' when the option is found, but 85 | left unchanged if the option is not found. 86 | 87 | To have a long-named option do something other than set an `int' to 88 | a compiled-in constant, such as set a value from `optarg', set the 89 | option's `flag' field to zero and its `val' field to a nonzero 90 | value (the equivalent single-letter option character, if there is 91 | one). For long options that have a zero `flag' field, `getopt' 92 | returns the contents of the `val' field. */ 93 | 94 | struct option 95 | { 96 | # if (defined __STDC__ && __STDC__) || defined __cplusplus 97 | const char *name; 98 | # else 99 | char *name; 100 | # endif 101 | /* has_arg can't be an enum because some compilers complain about 102 | type mismatches in all the code that assumes it is an int. */ 103 | int has_arg; 104 | int *flag; 105 | int val; 106 | }; 107 | 108 | /* Names for the values of the `has_arg' field of `struct option'. */ 109 | 110 | # define no_argument 0 111 | # define required_argument 1 112 | # define optional_argument 2 113 | #endif /* need getopt */ 114 | 115 | 116 | /* Get definitions and prototypes for functions to process the 117 | arguments in ARGV (ARGC of them, minus the program name) for 118 | options given in OPTS. 119 | 120 | Return the option character from OPTS just read. Return -1 when 121 | there are no more options. For unrecognized options, or options 122 | missing arguments, `optopt' is set to the option letter, and '?' is 123 | returned. 124 | 125 | The OPTS string is a list of characters which are recognized option 126 | letters, optionally followed by colons, specifying that that letter 127 | takes an argument, to be placed in `optarg'. 128 | 129 | If a letter in OPTS is followed by two colons, its argument is 130 | optional. This behavior is specific to the GNU `getopt'. 131 | 132 | The argument `--' causes premature termination of argument 133 | scanning, explicitly telling `getopt' that there are no more 134 | options. 135 | 136 | If OPTS begins with `--', then non-option arguments are treated as 137 | arguments to the option '\0'. This behavior is specific to the GNU 138 | `getopt'. */ 139 | 140 | #if (defined __STDC__ && __STDC__) || defined __cplusplus 141 | # ifdef __GNU_LIBRARY__ 142 | /* Many other libraries have conflicting prototypes for getopt, with 143 | differences in the consts, in stdlib.h. To avoid compilation 144 | errors, only prototype getopt for the GNU C library. */ 145 | extern int getopt (int __argc, char *const *__argv, const char *__shortopts); 146 | # else /* not __GNU_LIBRARY__ */ 147 | extern int getopt (); 148 | # endif /* __GNU_LIBRARY__ */ 149 | 150 | # ifndef __need_getopt 151 | extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts, 152 | const struct option *__longopts, int *__longind); 153 | extern int getopt_long_only (int __argc, char *const *__argv, 154 | const char *__shortopts, 155 | const struct option *__longopts, int *__longind); 156 | 157 | /* Internal only. Users should not call this directly. */ 158 | extern int _getopt_internal (int __argc, char *const *__argv, 159 | const char *__shortopts, 160 | const struct option *__longopts, int *__longind, 161 | int __long_only); 162 | # endif 163 | #else /* not __STDC__ */ 164 | extern int getopt (); 165 | # ifndef __need_getopt 166 | extern int getopt_long (); 167 | extern int getopt_long_only (); 168 | 169 | extern int _getopt_internal (); 170 | # endif 171 | #endif /* __STDC__ */ 172 | 173 | #ifdef __cplusplus 174 | } 175 | #endif 176 | 177 | /* Make sure we later can get all the definitions and declarations. */ 178 | #undef __need_getopt 179 | 180 | #endif /* getopt.h */ 181 | -------------------------------------------------------------------------------- /rsp_tcp/include_ext/md5.sum: -------------------------------------------------------------------------------- 1 | cfdb57a8e93ee1ed9322908f49a750d5 pthread.h 2 | 37cb7e0c214b62b37a57ab46d72e1034 sched.h 3 | 2c928d43a30ca0b0ad39a0accbae775e semaphore.h 4 | -------------------------------------------------------------------------------- /rsp_tcp/include_ext/mir_sdr.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2013 Mirics Ltd, All Rights Reserved 3 | // 4 | 5 | #ifndef MIR_SDR_H 6 | #define MIR_SDR_H 7 | 8 | #ifndef _MIR_SDR_QUALIFIER 9 | #if !defined(STATIC_LIB) && (defined(_M_X64) || defined(_M_IX86)) 10 | #define _MIR_SDR_QUALIFIER __declspec(dllimport) 11 | #elif defined(STATIC_LIB) || defined(__GNUC__) 12 | #define _MIR_SDR_QUALIFIER 13 | #endif 14 | #endif // _MIR_SDR_QUALIFIER 15 | 16 | // Application code should check that it is compiled against the same API version 17 | // mir_sdr_ApiVersion() returns the API version 18 | #define MIR_SDR_API_VERSION (float)(2.13) 19 | 20 | #if defined(ANDROID) || defined(__ANDROID__) 21 | // Android requires a mechanism to request info from Java application 22 | typedef enum 23 | { 24 | mir_sdr_GetFd = 0, 25 | mir_sdr_FreeFd = 1, 26 | mir_sdr_DevNotFound = 2, 27 | mir_sdr_DevRemoved = 3, 28 | mir_sdr_GetVendorId = 4, 29 | mir_sdr_GetProductId = 5, 30 | mir_sdr_GetRevId = 6, 31 | mir_sdr_GetDeviceId = 7 32 | } mir_sdr_JavaReqT; 33 | 34 | typedef int (*mir_sdr_SendJavaReq_t)(mir_sdr_JavaReqT cmd, char *path, char *serNum); 35 | #endif 36 | 37 | typedef enum 38 | { 39 | mir_sdr_Success = 0, 40 | mir_sdr_Fail = 1, 41 | mir_sdr_InvalidParam = 2, 42 | mir_sdr_OutOfRange = 3, 43 | mir_sdr_GainUpdateError = 4, 44 | mir_sdr_RfUpdateError = 5, 45 | mir_sdr_FsUpdateError = 6, 46 | mir_sdr_HwError = 7, 47 | mir_sdr_AliasingError = 8, 48 | mir_sdr_AlreadyInitialised = 9, 49 | mir_sdr_NotInitialised = 10, 50 | mir_sdr_NotEnabled = 11, 51 | mir_sdr_HwVerError = 12, 52 | mir_sdr_OutOfMemError = 13, 53 | mir_sdr_HwRemoved = 14 54 | } mir_sdr_ErrT; 55 | 56 | typedef enum 57 | { 58 | mir_sdr_BW_Undefined = 0, 59 | mir_sdr_BW_0_200 = 200, 60 | mir_sdr_BW_0_300 = 300, 61 | mir_sdr_BW_0_600 = 600, 62 | mir_sdr_BW_1_536 = 1536, 63 | mir_sdr_BW_5_000 = 5000, 64 | mir_sdr_BW_6_000 = 6000, 65 | mir_sdr_BW_7_000 = 7000, 66 | mir_sdr_BW_8_000 = 8000 67 | } mir_sdr_Bw_MHzT; 68 | 69 | typedef enum 70 | { 71 | mir_sdr_IF_Undefined = -1, 72 | mir_sdr_IF_Zero = 0, 73 | mir_sdr_IF_0_450 = 450, 74 | mir_sdr_IF_1_620 = 1620, 75 | mir_sdr_IF_2_048 = 2048 76 | } mir_sdr_If_kHzT; 77 | 78 | typedef enum 79 | { 80 | mir_sdr_ISOCH = 0, 81 | mir_sdr_BULK = 1 82 | } mir_sdr_TransferModeT; 83 | 84 | typedef enum 85 | { 86 | mir_sdr_CHANGE_NONE = 0x00, 87 | mir_sdr_CHANGE_GR = 0x01, 88 | mir_sdr_CHANGE_FS_FREQ = 0x02, 89 | mir_sdr_CHANGE_RF_FREQ = 0x04, 90 | mir_sdr_CHANGE_BW_TYPE = 0x08, 91 | mir_sdr_CHANGE_IF_TYPE = 0x10, 92 | mir_sdr_CHANGE_LO_MODE = 0x20, 93 | mir_sdr_CHANGE_AM_PORT = 0x40 94 | } mir_sdr_ReasonForReinitT; 95 | 96 | typedef enum 97 | { 98 | mir_sdr_LO_Undefined = 0, 99 | mir_sdr_LO_Auto = 1, 100 | mir_sdr_LO_120MHz = 2, 101 | mir_sdr_LO_144MHz = 3, 102 | mir_sdr_LO_168MHz = 4 103 | } mir_sdr_LoModeT; 104 | 105 | typedef enum 106 | { 107 | mir_sdr_BAND_AM_LO = 0, 108 | mir_sdr_BAND_AM_MID = 1, 109 | mir_sdr_BAND_AM_HI = 2, 110 | mir_sdr_BAND_VHF = 3, 111 | mir_sdr_BAND_3 = 4, 112 | mir_sdr_BAND_X = 5, 113 | mir_sdr_BAND_4_5 = 6, 114 | mir_sdr_BAND_L = 7 115 | } mir_sdr_BandT; 116 | 117 | typedef enum 118 | { 119 | mir_sdr_USE_SET_GR = 0, 120 | mir_sdr_USE_SET_GR_ALT_MODE = 1, 121 | mir_sdr_USE_RSP_SET_GR = 2 122 | } mir_sdr_SetGrModeT; 123 | 124 | typedef enum 125 | { 126 | mir_sdr_RSPII_BAND_UNKNOWN = 0, 127 | mir_sdr_RSPII_BAND_AM_LO = 1, 128 | mir_sdr_RSPII_BAND_AM_MID = 2, 129 | mir_sdr_RSPII_BAND_AM_HI = 3, 130 | mir_sdr_RSPII_BAND_VHF = 4, 131 | mir_sdr_RSPII_BAND_3 = 5, 132 | mir_sdr_RSPII_BAND_X_LO = 6, 133 | mir_sdr_RSPII_BAND_X_MID = 7, 134 | mir_sdr_RSPII_BAND_X_HI = 8, 135 | mir_sdr_RSPII_BAND_4_5 = 9, 136 | mir_sdr_RSPII_BAND_L = 10 137 | } mir_sdr_RSPII_BandT; 138 | 139 | typedef enum 140 | { 141 | mir_sdr_RSPII_ANTENNA_A = 5, 142 | mir_sdr_RSPII_ANTENNA_B = 6 143 | } mir_sdr_RSPII_AntennaSelectT; 144 | 145 | typedef enum 146 | { 147 | mir_sdr_AGC_DISABLE = 0, 148 | mir_sdr_AGC_100HZ = 1, 149 | mir_sdr_AGC_50HZ = 2, 150 | mir_sdr_AGC_5HZ = 3 151 | } mir_sdr_AgcControlT; 152 | 153 | typedef enum 154 | { 155 | mir_sdr_GAIN_MESSAGE_START_ID = 0x80000000, 156 | mir_sdr_ADC_OVERLOAD_DETECTED = mir_sdr_GAIN_MESSAGE_START_ID + 1, 157 | mir_sdr_ADC_OVERLOAD_CORRECTED = mir_sdr_GAIN_MESSAGE_START_ID + 2 158 | } mir_sdr_GainMessageIdT; 159 | 160 | typedef enum 161 | { 162 | mir_sdr_EXTENDED_MIN_GR = 0, 163 | mir_sdr_NORMAL_MIN_GR = 20 164 | } mir_sdr_MinGainReductionT; 165 | 166 | typedef struct 167 | { 168 | char *SerNo; 169 | char *DevNm; 170 | unsigned char hwVer; 171 | unsigned char devAvail; 172 | } mir_sdr_DeviceT; 173 | 174 | typedef struct 175 | { 176 | float curr; 177 | float max; 178 | float min; 179 | } mir_sdr_GainValuesT; 180 | 181 | typedef enum 182 | { 183 | mir_sdr_rspDuo_Tuner_1 = 1, 184 | mir_sdr_rspDuo_Tuner_2 = 2, 185 | } mir_sdr_rspDuo_TunerSelT; 186 | 187 | // mir_sdr_StreamInit() callback function prototypes 188 | typedef void (*mir_sdr_StreamCallback_t)(short *xi, short *xq, unsigned int firstSampleNum, int grChanged, int rfChanged, int fsChanged, unsigned int numSamples, unsigned int reset, unsigned int hwRemoved, void *cbContext); 189 | typedef void (*mir_sdr_GainChangeCallback_t)(unsigned int gRdB, unsigned int lnaGRdB, void *cbContext); 190 | 191 | typedef mir_sdr_ErrT (*mir_sdr_Init_t)(int gRdB, double fsMHz, double rfMHz, mir_sdr_Bw_MHzT bwType, mir_sdr_If_kHzT ifType, int *samplesPerPacket); 192 | typedef mir_sdr_ErrT (*mir_sdr_Uninit_t)(void); 193 | typedef mir_sdr_ErrT (*mir_sdr_ReadPacket_t)(short *xi, short *xq, unsigned int *firstSampleNum, int *grChanged, int *rfChanged, int *fsChanged); 194 | typedef mir_sdr_ErrT (*mir_sdr_SetRf_t)(double drfHz, int abs, int syncUpdate); 195 | typedef mir_sdr_ErrT (*mir_sdr_SetFs_t)(double dfsHz, int abs, int syncUpdate, int reCal); 196 | typedef mir_sdr_ErrT (*mir_sdr_SetGr_t)(int gRdB, int abs, int syncUpdate); 197 | typedef mir_sdr_ErrT (*mir_sdr_SetGrParams_t)(int minimumGr, int lnaGrThreshold); 198 | typedef mir_sdr_ErrT (*mir_sdr_SetDcMode_t)(int dcCal, int speedUp); 199 | typedef mir_sdr_ErrT (*mir_sdr_SetDcTrackTime_t)(int trackTime); 200 | typedef mir_sdr_ErrT (*mir_sdr_SetSyncUpdateSampleNum_t)(unsigned int sampleNum); 201 | typedef mir_sdr_ErrT (*mir_sdr_SetSyncUpdatePeriod_t)(unsigned int period); 202 | typedef mir_sdr_ErrT (*mir_sdr_ApiVersion_t)(float *version); 203 | typedef mir_sdr_ErrT (*mir_sdr_ResetUpdateFlags_t)(int resetGainUpdate, int resetRfUpdate, int resetFsUpdate); 204 | #if defined(ANDROID) || defined(__ANDROID__) 205 | typedef mir_sdr_ErrT (*mir_sdr_SetJavaReqCallback_t)(mir_sdr_SendJavaReq_t sendJavaReq); 206 | #endif 207 | typedef mir_sdr_ErrT (*mir_sdr_SetTransferMode_t)(mir_sdr_TransferModeT mode); 208 | typedef mir_sdr_ErrT (*mir_sdr_DownConvert_t)(short *in, short *xi, short *xq, unsigned int samplesPerPacket, mir_sdr_If_kHzT ifType, unsigned int M, unsigned int preReset); 209 | typedef mir_sdr_ErrT (*mir_sdr_SetParam_t)(unsigned int id, unsigned int value); 210 | typedef mir_sdr_ErrT (*mir_sdr_SetPpm_t)(double ppm); 211 | typedef mir_sdr_ErrT (*mir_sdr_SetLoMode_t)(mir_sdr_LoModeT loMode); 212 | typedef mir_sdr_ErrT (*mir_sdr_SetGrAltMode_t)(int *gRidx, int LNAstate, int *gRdBsystem, int abs, int syncUpdate); 213 | typedef mir_sdr_ErrT (*mir_sdr_DCoffsetIQimbalanceControl_t)(unsigned int DCenable, unsigned int IQenable); 214 | typedef mir_sdr_ErrT (*mir_sdr_DecimateControl_t)(unsigned int enable, unsigned int decimationFactor, unsigned int wideBandSignal); 215 | typedef mir_sdr_ErrT (*mir_sdr_AgcControl_t)(mir_sdr_AgcControlT enable, int setPoint_dBfs, int knee_dBfs, unsigned int decay_ms, unsigned int hang_ms, int syncUpdate, int LNAstate); 216 | typedef mir_sdr_ErrT (*mir_sdr_StreamInit_t)(int *gRdB, double fsMHz, double rfMHz, mir_sdr_Bw_MHzT bwType, mir_sdr_If_kHzT ifType, int LNAstate, int *gRdBsystem, mir_sdr_SetGrModeT setGrMode, int *samplesPerPacket, mir_sdr_StreamCallback_t StreamCbFn, mir_sdr_GainChangeCallback_t GainChangeCbFn, void *cbContext); 217 | typedef mir_sdr_ErrT (*mir_sdr_StreamUninit_t)(void); 218 | typedef mir_sdr_ErrT (*mir_sdr_Reinit_t)(int *gRdB, double fsMHz, double rfMHz, mir_sdr_Bw_MHzT bwType, mir_sdr_If_kHzT ifType, mir_sdr_LoModeT loMode, int LNAstate, int *gRdBsystem, mir_sdr_SetGrModeT setGrMode, int *samplesPerPacket, mir_sdr_ReasonForReinitT reasonForReinit); 219 | typedef mir_sdr_ErrT (*mir_sdr_GetGrByFreq_t)(double rfMHz, mir_sdr_BandT *band, int *gRdB, int LNAstate, int *gRdBsystem, mir_sdr_SetGrModeT setGrMode); 220 | typedef mir_sdr_ErrT (*mir_sdr_DebugEnable_t)(unsigned int enable); 221 | typedef mir_sdr_ErrT (*mir_sdr_GetCurrentGain_t)(mir_sdr_GainValuesT *gainVals); 222 | typedef mir_sdr_ErrT (*mir_sdr_GainChangeCallbackMessageReceived_t)(void); 223 | 224 | typedef mir_sdr_ErrT (*mir_sdr_GetDevices_t)(mir_sdr_DeviceT *devices, unsigned int *numDevs, unsigned int maxDevs); 225 | typedef mir_sdr_ErrT (*mir_sdr_SetDeviceIdx_t)(unsigned int idx); 226 | typedef mir_sdr_ErrT (*mir_sdr_ReleaseDeviceIdx_t)(void); 227 | typedef mir_sdr_ErrT (*mir_sdr_GetHwVersion_t)(unsigned char *ver); 228 | typedef mir_sdr_ErrT (*mir_sdr_RSPII_AntennaControl_t)(mir_sdr_RSPII_AntennaSelectT select); 229 | typedef mir_sdr_ErrT (*mir_sdr_RSPII_ExternalReferenceControl_t)(unsigned int output_enable); 230 | typedef mir_sdr_ErrT (*mir_sdr_RSPII_BiasTControl_t)(unsigned int enable); 231 | typedef mir_sdr_ErrT (*mir_sdr_RSPII_RfNotchEnable_t)(unsigned int enable); 232 | 233 | typedef mir_sdr_ErrT (*mir_sdr_RSP_SetGr_t)(int gRdB, int LNAstate, int abs, int syncUpdate); 234 | typedef mir_sdr_ErrT (*mir_sdr_RSP_SetGrLimits_t)(mir_sdr_MinGainReductionT minGr); 235 | 236 | typedef mir_sdr_ErrT (*mir_sdr_AmPortSelect_t)(int port); 237 | 238 | typedef mir_sdr_ErrT (*mir_sdr_rsp1a_BiasT_t)(int enable); 239 | typedef mir_sdr_ErrT (*mir_sdr_rsp1a_DabNotch_t)(int enable); 240 | typedef mir_sdr_ErrT (*mir_sdr_rsp1a_BroadcastNotch_t)(int enable); 241 | 242 | typedef mir_sdr_ErrT (*mir_sdr_rspDuo_TunerSel_t)(mir_sdr_rspDuo_TunerSelT sel); 243 | typedef mir_sdr_ErrT (*mir_sdr_rspDuo_ExtRef_t)(int enable); 244 | typedef mir_sdr_ErrT (*mir_sdr_rspDuo_BiasT_t)(int enable); 245 | typedef mir_sdr_ErrT (*mir_sdr_rspDuo_Tuner1AmNotch_t)(int enable); 246 | typedef mir_sdr_ErrT (*mir_sdr_rspDuo_BroadcastNotch_t)(int enable); 247 | typedef mir_sdr_ErrT (*mir_sdr_rspDuo_DabNotch_t)(int enable); 248 | 249 | // API function definitions 250 | #ifdef __cplusplus 251 | extern "C" 252 | { 253 | #endif 254 | 255 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_Init(int gRdB, double fsMHz, double rfMHz, mir_sdr_Bw_MHzT bwType, mir_sdr_If_kHzT ifType, int *samplesPerPacket); 256 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_Uninit(void); 257 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_ReadPacket(short *xi, short *xq, unsigned int *firstSampleNum, int *grChanged, int *rfChanged, int *fsChanged); 258 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetRf(double drfHz, int abs, int syncUpdate); 259 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetFs(double dfsHz, int abs, int syncUpdate, int reCal); 260 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetGr(int gRdB, int abs, int syncUpdate); 261 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetGrParams(int minimumGr, int lnaGrThreshold); 262 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetDcMode(int dcCal, int speedUp); 263 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetDcTrackTime(int trackTime); 264 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetSyncUpdateSampleNum(unsigned int sampleNum); 265 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetSyncUpdatePeriod(unsigned int period); 266 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_ApiVersion(float *version); // Called by application to retrieve version of API used to create Dll 267 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_ResetUpdateFlags(int resetGainUpdate, int resetRfUpdate, int resetFsUpdate); 268 | #if defined(ANDROID) || defined(__ANDROID__) 269 | // This function provides a machanism for the Java application to set 270 | // the callback function used to send request to it 271 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetJavaReqCallback(mir_sdr_SendJavaReq_t sendJavaReq); 272 | #endif 273 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetTransferMode(mir_sdr_TransferModeT mode); 274 | /* 275 | * This following function will only operate correctly for the parameters detailed in the table below: 276 | * 277 | * IF freq | Signal BW | Input Sample Rate | Output Sample Rate | Required Decimation Factor 278 | * ------------------------------------------------------------------------------------------- 279 | * 450kHz | 200kHz | 2000kHz | 500kHz | M=4 280 | * 450kHz | 300kHz | 2000kHz | 500kHz | M=4 281 | * 450kHz | 600kHz | 2000kHz | 1000kHz | M=2 282 | * 2048kHz | 1536kHz | 8192kHz | 2048kHz | M=4 283 | * 284 | * If preReset == 1, then the filter state will be reset to 0 before starting the filtering operation. 285 | */ 286 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_DownConvert(short *in, short *xi, short *xq, unsigned int samplesPerPacket, mir_sdr_If_kHzT ifType, unsigned int M, unsigned int preReset); 287 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetParam(unsigned int id, unsigned int value); // This MAY be called before mir_sdr_Init() 288 | 289 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetPpm(double ppm); // This MAY be called before mir_sdr_Init() 290 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetLoMode(mir_sdr_LoModeT loMode); // This MUST be called before mir_sdr_Init()/mir_sdr_StreamInit() - otherwise use mir_sdr_Reinit() 291 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetGrAltMode(int *gRidx, int LNAstate, int *gRdBsystem, int abs, int syncUpdate); 292 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_DCoffsetIQimbalanceControl(unsigned int DCenable, unsigned int IQenable); 293 | /* 294 | * Valid decimation factors for the following function are 2, 4, 8, 16 or 32 only 295 | * Setting wideBandSignal=1 will use a slower filter but minimise the in-band roll-off 296 | */ 297 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_DecimateControl(unsigned int enable, unsigned int decimationFactor, unsigned int wideBandSignal); 298 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_AgcControl(mir_sdr_AgcControlT enable, int setPoint_dBfs, int knee_dBfs, unsigned int decay_ms, unsigned int hang_ms, int syncUpdate, int LNAstate); 299 | /* 300 | * mir_sdr_StreamInit() replaces mir_sdr_Init() and sets up a thread (or chain of threads) inside the API which will perform the processing chain (shown below), 301 | * and then use the callback function to return the data to the calling application/plug-in. 302 | * Processing chain (in order): 303 | * mir_sdr_ReadPacket() 304 | * DCoffsetCorrection() - LIF mode - enabled by default 305 | * DownConvert() - automatically enabled if the parameters shown for mir_sdr_DownConvert() are selected 306 | * Decimate() - disabled by default 307 | * DCoffsetCorrection() - ZIF mode - enabled by default 308 | * IQimbalanceCorrection() - enabled by default 309 | * Agc() - disabled by default 310 | */ 311 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_StreamInit(int *gRdB, double fsMHz, double rfMHz, mir_sdr_Bw_MHzT bwType, mir_sdr_If_kHzT ifType, int LNAstate, int *gRdBsystem, mir_sdr_SetGrModeT setGrMode, int *samplesPerPacket, mir_sdr_StreamCallback_t StreamCbFn, mir_sdr_GainChangeCallback_t GainChangeCbFn, void *cbContext); 312 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_StreamUninit(void); 313 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_Reinit(int *gRdB, double fsMHz, double rfMHz, mir_sdr_Bw_MHzT bwType, mir_sdr_If_kHzT ifType, mir_sdr_LoModeT loMode, int LNAstate, int *gRdBsystem, mir_sdr_SetGrModeT setGrMode, int *samplesPerPacket, mir_sdr_ReasonForReinitT reasonForReinit); 314 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_GetGrByFreq(double rfMHz, mir_sdr_BandT *band, int *gRdB, int LNAstate, int *gRdBsystem, mir_sdr_SetGrModeT setGrMode); 315 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_DebugEnable(unsigned int enable); 316 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_GetCurrentGain(mir_sdr_GainValuesT *gainVals); 317 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_GainChangeCallbackMessageReceived(void); 318 | 319 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_GetDevices(mir_sdr_DeviceT *devices, unsigned int *numDevs, unsigned int maxDevs); 320 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_SetDeviceIdx(unsigned int idx); 321 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_ReleaseDeviceIdx(void); 322 | /* 323 | * Uninit: ver = 0 324 | * RSPI : ver = 1 325 | * RSPII: ver = 2 326 | */ 327 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_GetHwVersion(unsigned char *ver); 328 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_RSPII_AntennaControl(mir_sdr_RSPII_AntennaSelectT select); 329 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_RSPII_ExternalReferenceControl(unsigned int output_enable); 330 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_RSPII_BiasTControl(unsigned int enable); 331 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_RSPII_RfNotchEnable(unsigned int enable); 332 | 333 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_RSP_SetGr(int gRdB, int LNAstate, int abs, int syncUpdate); 334 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_RSP_SetGrLimits(mir_sdr_MinGainReductionT minGr); 335 | 336 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_AmPortSelect(int port); // If called after mir_sdr_Init() a call to mir_sdr_Reinit(..., reasonForReinit = mir_sdr_CHANGE_AM_PORT) 337 | // is also required to change the port 338 | 339 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rsp1a_BiasT(int enable); 340 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rsp1a_DabNotch(int enable); 341 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rsp1a_BroadcastNotch(int enable); 342 | 343 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rspDuo_TunerSel(mir_sdr_rspDuo_TunerSelT sel); 344 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rspDuo_ExtRef(int enable); 345 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rspDuo_BiasT(int enable); 346 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rspDuo_Tuner1AmNotch(int enable); 347 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rspDuo_BroadcastNotch(int enable); 348 | _MIR_SDR_QUALIFIER mir_sdr_ErrT mir_sdr_rspDuo_DabNotch(int enable); 349 | 350 | #ifdef __cplusplus 351 | } 352 | #endif 353 | 354 | #endif //MIR_SDR_H 355 | -------------------------------------------------------------------------------- /rsp_tcp/include_ext/sched.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Module: sched.h 3 | * 4 | * Purpose: 5 | * Provides an implementation of POSIX realtime extensions 6 | * as defined in 7 | * 8 | * POSIX 1003.1b-1993 (POSIX.1b) 9 | * 10 | * -------------------------------------------------------------------------- 11 | * 12 | * Pthreads-win32 - POSIX Threads Library for Win32 13 | * Copyright(C) 1998 John E. Bossom 14 | * Copyright(C) 1999,2005 Pthreads-win32 contributors 15 | * 16 | * Contact Email: rpj@callisto.canberra.edu.au 17 | * 18 | * The current list of contributors is contained 19 | * in the file CONTRIBUTORS included with the source 20 | * code distribution. The list can also be seen at the 21 | * following World Wide Web location: 22 | * http://sources.redhat.com/pthreads-win32/contributors.html 23 | * 24 | * This library is free software; you can redistribute it and/or 25 | * modify it under the terms of the GNU Lesser General Public 26 | * License as published by the Free Software Foundation; either 27 | * version 2 of the License, or (at your option) any later version. 28 | * 29 | * This library is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 32 | * Lesser General Public License for more details. 33 | * 34 | * You should have received a copy of the GNU Lesser General Public 35 | * License along with this library in the file COPYING.LIB; 36 | * if not, write to the Free Software Foundation, Inc., 37 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 38 | */ 39 | #if !defined(_SCHED_H) 40 | #define _SCHED_H 41 | 42 | #undef PTW32_SCHED_LEVEL 43 | 44 | #if defined(_POSIX_SOURCE) 45 | #define PTW32_SCHED_LEVEL 0 46 | /* Early POSIX */ 47 | #endif 48 | 49 | #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 50 | #undef PTW32_SCHED_LEVEL 51 | #define PTW32_SCHED_LEVEL 1 52 | /* Include 1b, 1c and 1d */ 53 | #endif 54 | 55 | #if defined(INCLUDE_NP) 56 | #undef PTW32_SCHED_LEVEL 57 | #define PTW32_SCHED_LEVEL 2 58 | /* Include Non-Portable extensions */ 59 | #endif 60 | 61 | #define PTW32_SCHED_LEVEL_MAX 3 62 | 63 | #if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_SCHED_LEVEL) 64 | #define PTW32_SCHED_LEVEL PTW32_SCHED_LEVEL_MAX 65 | /* Include everything */ 66 | #endif 67 | 68 | 69 | #if defined(__GNUC__) && !defined(__declspec) 70 | # error Please upgrade your GNU compiler to one that supports __declspec. 71 | #endif 72 | 73 | /* 74 | * When building the library, you should define PTW32_BUILD so that 75 | * the variables/functions are exported correctly. When using the library, 76 | * do NOT define PTW32_BUILD, and then the variables/functions will 77 | * be imported correctly. 78 | */ 79 | #if !defined(PTW32_STATIC_LIB) 80 | # if defined(PTW32_BUILD) 81 | # define PTW32_DLLPORT __declspec (dllexport) 82 | # else 83 | # define PTW32_DLLPORT __declspec (dllimport) 84 | # endif 85 | #else 86 | # define PTW32_DLLPORT 87 | #endif 88 | 89 | /* 90 | * This is a duplicate of what is in the autoconf config.h, 91 | * which is only used when building the pthread-win32 libraries. 92 | */ 93 | 94 | #if !defined(PTW32_CONFIG_H) 95 | # if defined(WINCE) 96 | # define NEED_ERRNO 97 | # define NEED_SEM 98 | # endif 99 | # if defined(__MINGW64__) 100 | # define HAVE_STRUCT_TIMESPEC 101 | # define HAVE_MODE_T 102 | # elif defined(_UWIN) || defined(__MINGW32__) 103 | # define HAVE_MODE_T 104 | # endif 105 | #endif 106 | 107 | /* 108 | * 109 | */ 110 | 111 | #if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX 112 | #if defined(NEED_ERRNO) 113 | #include "need_errno.h" 114 | #else 115 | #include 116 | #endif 117 | #endif /* PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX */ 118 | 119 | #if (defined(__MINGW64__) || defined(__MINGW32__)) || defined(_UWIN) 120 | # if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX 121 | /* For pid_t */ 122 | # include 123 | /* Required by Unix 98 */ 124 | # include 125 | # else 126 | typedef int pid_t; 127 | # endif 128 | #else 129 | typedef int pid_t; 130 | #endif 131 | 132 | /* Thread scheduling policies */ 133 | 134 | enum { 135 | SCHED_OTHER = 0, 136 | SCHED_FIFO, 137 | SCHED_RR, 138 | SCHED_MIN = SCHED_OTHER, 139 | SCHED_MAX = SCHED_RR 140 | }; 141 | 142 | struct sched_param { 143 | int sched_priority; 144 | }; 145 | 146 | #if defined(__cplusplus) 147 | extern "C" 148 | { 149 | #endif /* __cplusplus */ 150 | 151 | PTW32_DLLPORT int __cdecl sched_yield (void); 152 | 153 | PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy); 154 | 155 | PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy); 156 | 157 | PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy); 158 | 159 | PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid); 160 | 161 | /* 162 | * Note that this macro returns ENOTSUP rather than 163 | * ENOSYS as might be expected. However, returning ENOSYS 164 | * should mean that sched_get_priority_{min,max} are 165 | * not implemented as well as sched_rr_get_interval. 166 | * This is not the case, since we just don't support 167 | * round-robin scheduling. Therefore I have chosen to 168 | * return the same value as sched_setscheduler when 169 | * SCHED_RR is passed to it. 170 | */ 171 | #define sched_rr_get_interval(_pid, _interval) \ 172 | ( errno = ENOTSUP, (int) -1 ) 173 | 174 | 175 | #if defined(__cplusplus) 176 | } /* End of extern "C" */ 177 | #endif /* __cplusplus */ 178 | 179 | #undef PTW32_SCHED_LEVEL 180 | #undef PTW32_SCHED_LEVEL_MAX 181 | 182 | #endif /* !_SCHED_H */ 183 | 184 | -------------------------------------------------------------------------------- /rsp_tcp/include_ext/semaphore.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Module: semaphore.h 3 | * 4 | * Purpose: 5 | * Semaphores aren't actually part of the PThreads standard. 6 | * They are defined by the POSIX Standard: 7 | * 8 | * POSIX 1003.1b-1993 (POSIX.1b) 9 | * 10 | * -------------------------------------------------------------------------- 11 | * 12 | * Pthreads-win32 - POSIX Threads Library for Win32 13 | * Copyright(C) 1998 John E. Bossom 14 | * Copyright(C) 1999,2005 Pthreads-win32 contributors 15 | * 16 | * Contact Email: rpj@callisto.canberra.edu.au 17 | * 18 | * The current list of contributors is contained 19 | * in the file CONTRIBUTORS included with the source 20 | * code distribution. The list can also be seen at the 21 | * following World Wide Web location: 22 | * http://sources.redhat.com/pthreads-win32/contributors.html 23 | * 24 | * This library is free software; you can redistribute it and/or 25 | * modify it under the terms of the GNU Lesser General Public 26 | * License as published by the Free Software Foundation; either 27 | * version 2 of the License, or (at your option) any later version. 28 | * 29 | * This library is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 32 | * Lesser General Public License for more details. 33 | * 34 | * You should have received a copy of the GNU Lesser General Public 35 | * License along with this library in the file COPYING.LIB; 36 | * if not, write to the Free Software Foundation, Inc., 37 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 38 | */ 39 | #if !defined( SEMAPHORE_H ) 40 | #define SEMAPHORE_H 41 | 42 | #undef PTW32_SEMAPHORE_LEVEL 43 | 44 | #if defined(_POSIX_SOURCE) 45 | #define PTW32_SEMAPHORE_LEVEL 0 46 | /* Early POSIX */ 47 | #endif 48 | 49 | #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 50 | #undef PTW32_SEMAPHORE_LEVEL 51 | #define PTW32_SEMAPHORE_LEVEL 1 52 | /* Include 1b, 1c and 1d */ 53 | #endif 54 | 55 | #if defined(INCLUDE_NP) 56 | #undef PTW32_SEMAPHORE_LEVEL 57 | #define PTW32_SEMAPHORE_LEVEL 2 58 | /* Include Non-Portable extensions */ 59 | #endif 60 | 61 | #define PTW32_SEMAPHORE_LEVEL_MAX 3 62 | 63 | #if !defined(PTW32_SEMAPHORE_LEVEL) 64 | #define PTW32_SEMAPHORE_LEVEL PTW32_SEMAPHORE_LEVEL_MAX 65 | /* Include everything */ 66 | #endif 67 | 68 | #if defined(__GNUC__) && ! defined (__declspec) 69 | # error Please upgrade your GNU compiler to one that supports __declspec. 70 | #endif 71 | 72 | /* 73 | * When building the library, you should define PTW32_BUILD so that 74 | * the variables/functions are exported correctly. When using the library, 75 | * do NOT define PTW32_BUILD, and then the variables/functions will 76 | * be imported correctly. 77 | */ 78 | #if !defined(PTW32_STATIC_LIB) 79 | # if defined(PTW32_BUILD) 80 | # define PTW32_DLLPORT __declspec (dllexport) 81 | # else 82 | # define PTW32_DLLPORT __declspec (dllimport) 83 | # endif 84 | #else 85 | # define PTW32_DLLPORT 86 | #endif 87 | 88 | /* 89 | * This is a duplicate of what is in the autoconf config.h, 90 | * which is only used when building the pthread-win32 libraries. 91 | */ 92 | 93 | #if !defined(PTW32_CONFIG_H) 94 | # if defined(WINCE) 95 | # define NEED_ERRNO 96 | # define NEED_SEM 97 | # endif 98 | # if defined(__MINGW64__) 99 | # define HAVE_STRUCT_TIMESPEC 100 | # define HAVE_MODE_T 101 | # elif defined(_UWIN) || defined(__MINGW32__) 102 | # define HAVE_MODE_T 103 | # endif 104 | #endif 105 | 106 | /* 107 | * 108 | */ 109 | 110 | #if PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX 111 | #if defined(NEED_ERRNO) 112 | #include "need_errno.h" 113 | #else 114 | #include 115 | #endif 116 | #endif /* PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX */ 117 | 118 | #define _POSIX_SEMAPHORES 119 | 120 | #if defined(__cplusplus) 121 | extern "C" 122 | { 123 | #endif /* __cplusplus */ 124 | 125 | #if !defined(HAVE_MODE_T) 126 | typedef unsigned int mode_t; 127 | #endif 128 | 129 | 130 | typedef struct sem_t_ * sem_t; 131 | 132 | PTW32_DLLPORT int __cdecl sem_init (sem_t * sem, 133 | int pshared, 134 | unsigned int value); 135 | 136 | PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem); 137 | 138 | PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem); 139 | 140 | PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem); 141 | 142 | PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem, 143 | const struct timespec * abstime); 144 | 145 | PTW32_DLLPORT int __cdecl sem_post (sem_t * sem); 146 | 147 | PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem, 148 | int count); 149 | 150 | PTW32_DLLPORT int __cdecl sem_open (const char * name, 151 | int oflag, 152 | mode_t mode, 153 | unsigned int value); 154 | 155 | PTW32_DLLPORT int __cdecl sem_close (sem_t * sem); 156 | 157 | PTW32_DLLPORT int __cdecl sem_unlink (const char * name); 158 | 159 | PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem, 160 | int * sval); 161 | 162 | #if defined(__cplusplus) 163 | } /* End of extern "C" */ 164 | #endif /* __cplusplus */ 165 | 166 | #undef PTW32_SEMAPHORE_LEVEL 167 | #undef PTW32_SEMAPHORE_LEVEL_MAX 168 | 169 | #endif /* !SEMAPHORE_H */ 170 | -------------------------------------------------------------------------------- /rsp_tcp/lib32/mir_sdr_api.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/rsp_tcp/lib32/mir_sdr_api.dll -------------------------------------------------------------------------------- /rsp_tcp/lib32/mir_sdr_api.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/rsp_tcp/lib32/mir_sdr_api.lib -------------------------------------------------------------------------------- /rsp_tcp/lib32/pthreadVC2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/rsp_tcp/lib32/pthreadVC2.dll -------------------------------------------------------------------------------- /rsp_tcp/lib32/pthreadVC2.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/rsp_tcp/lib32/pthreadVC2.lib -------------------------------------------------------------------------------- /rsp_tcp/lib64/mir_sdr_api.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/rsp_tcp/lib64/mir_sdr_api.dll -------------------------------------------------------------------------------- /rsp_tcp/lib64/mir_sdr_api.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/rsp_tcp/lib64/mir_sdr_api.lib -------------------------------------------------------------------------------- /rsp_tcp/lib64/msvcr100.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/rsp_tcp/lib64/msvcr100.dll -------------------------------------------------------------------------------- /rsp_tcp/lib64/pthreadVC2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/rsp_tcp/lib64/pthreadVC2.dll -------------------------------------------------------------------------------- /rsp_tcp/lib64/pthreadVC2.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softsyst/RSP2_tcp/3633fb0de5871a8b7c95a4fb40e47174eea114f3/rsp_tcp/lib64/pthreadVC2.lib -------------------------------------------------------------------------------- /rsp_tcp/mir_sdr_device.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | ** RSP_tcp - TCP/IP I/Q Data Server for the sdrplay RSP2 3 | ** Copyright (C) 2017 Clem Schmidt, softsyst GmbH, http://www.softsyst.com 4 | ** 5 | ** This program is free software; you can redistribute it and/or modify 6 | ** it under the terms of the GNU General Public License as published by 7 | ** the Free Software Foundation; either version 2 of the License, or 8 | ** (at your option) any later version. 9 | ** 10 | ** This program is distributed in the hope that it will be useful, 11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ** GNU General Public License for more details. 14 | ** 15 | ** You should have received a copy of the GNU General Public License 16 | ** along with this program; if not, write to the Free Software 17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | ** 19 | **/ 20 | //#define TIME_MEAS 21 | #include "mir_sdr_device.h" 22 | #include "sdrGainTable.h" 23 | //#include "controlThread.h" 24 | #include "MeasTimeDiff.h" 25 | #include 26 | using namespace std; 27 | 28 | static LARGE_INTEGER Count1, Count2; 29 | 30 | mir_sdr_device::~mir_sdr_device() 31 | { 32 | pthread_mutex_destroy(&mutex_rxThreadStarted); 33 | pthread_cond_destroy(&started_cond); 34 | } 35 | 36 | mir_sdr_device::mir_sdr_device() 37 | { 38 | thrdRx = 0; 39 | pthread_mutex_init(&mutex_rxThreadStarted, NULL); 40 | pthread_cond_init(&started_cond, NULL); 41 | 42 | #ifdef TIME_MEAS 43 | Count1.LowPart = Count2.LowPart = 0; 44 | Count1.HighPart = Count2.HighPart = 0; 45 | #endif 46 | } 47 | 48 | void mir_sdr_device::createCtrlThread(const char* addr, int port) 49 | { 50 | cout << endl << "Creating ctrl thread..." << endl; 51 | if (thrdCtrl != 0) // just in case.. 52 | { 53 | pthread_cancel(*thrdCtrl); 54 | delete thrdCtrl; 55 | thrdCtrl = 0; 56 | } 57 | ctrlThreadExitFlag = false; 58 | ctrlThreadData.addr = addr; 59 | ctrlThreadData.port = port; 60 | ctrlThreadData.pDoExit = &ctrlThreadExitFlag; 61 | ctrlThreadData.wait = 500000; //0.5s 62 | ctrlThreadData.dev = this; 63 | 64 | thrdCtrl = new pthread_t(); 65 | 66 | pthread_attr_t attr; 67 | pthread_attr_init(&attr); 68 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 69 | int res = pthread_create(thrdCtrl, &attr, &ctrl_thread_fn, &ctrlThreadData); 70 | pthread_attr_destroy(&attr); 71 | } 72 | 73 | 74 | 75 | void mir_sdr_device::init(rsp_cmdLineArgs* pargs) 76 | { 77 | //From the command line 78 | currentFrequencyHz = pargs->Frequency; 79 | RequestedGain = pargs->Gain; 80 | initialSamplingRateHz = pargs->SamplingRate; 81 | bitWidth = (eBitWidth)pargs->BitWidth; 82 | antenna = pargs->Antenna; 83 | amPort = pargs->amPort; 84 | 85 | 86 | if (hwVer == 1) 87 | rxType = RSP1; 88 | else if (hwVer == 255) 89 | rxType = RSP1A; 90 | else if (hwVer == 2) 91 | { 92 | rxType = RSP2; 93 | err = mir_sdr_AmPortSelect(amPort); 94 | cout << "AM Port Select: " << amPort << endl; 95 | } 96 | else if (hwVer == 3) 97 | { 98 | rxType = RSPduo; 99 | err = mir_sdr_AmPortSelect(amPort); 100 | cout << "AM Port Select: " << amPort << endl; 101 | } 102 | else 103 | rxType = UNKNOWN; 104 | 105 | //if (rxType == RSP1 || rxType == RSP1A) 106 | flatGr = false; 107 | //else 108 | // flatGr = true; 109 | //if (rxType == RSP1 || rxType == RSP1A) 110 | //flatGr = false; 111 | //else 112 | // flatGr = true; 113 | } 114 | 115 | void mir_sdr_device::cleanup() 116 | { 117 | if (thrdRx != 0) // just in case.. 118 | { 119 | pthread_cancel(*thrdRx); 120 | delete thrdRx; 121 | thrdRx = 0; 122 | } 123 | } 124 | 125 | 126 | void mir_sdr_device::stop() 127 | { 128 | mir_sdr_ErrT err; 129 | 130 | if (!started) 131 | { 132 | cout << "Already Stopped. Nothing to do here."; 133 | return; 134 | } 135 | ctrlThreadExitFlag = true; 136 | cleanup(); 137 | 138 | //cout << "Stopping, calling mir_sdr_StreamUninit..." << endl; 139 | //err = mir_sdr_StreamUninit(); 140 | //cout << "mir_sdr_StreamUninit returned with: " << err << endl; 141 | //if (err == mir_sdr_Success) 142 | // cout << "StreamUnInit successful(0)" << endl; 143 | //else 144 | // cout << "StreamUnInit failed (1) with " << err << endl; 145 | //isStreaming = false; 146 | 147 | //err = mir_sdr_ReleaseDeviceIdx(); 148 | //cout << "\nmir_sdr_ReleaseDeviceIdx returned with: " << err << endl; 149 | //cout << "DeviceIndex released: " << DeviceIndex << endl; 150 | //started = false; 151 | 152 | //closesocket(remoteClient); 153 | //remoteClient = INVALID_SOCKET; 154 | //cout << "Socket closed\n\n"; 155 | } 156 | 157 | void mir_sdr_device::writeWelcomeString() const 158 | { 159 | BYTE buf0[] = "RTL0"; 160 | BYTE* buf = new BYTE[c_welcomeMessageLength]; 161 | memset(buf, 0, c_welcomeMessageLength); 162 | memcpy(buf, buf0, 4); 163 | buf[6] = bitWidth; 164 | buf[7] = rxType+6; //6:RSP1, 7: RSP1A, 8: RSP2 165 | buf[11] = gainConfiguration::GAIN_STEPS; 166 | buf[15] = 0x52; buf[16] = 0x53; buf[17] = 0x50; buf[18] = (int)rxType + 0x30; //"RSP2", interpreted e.g. by qirx 167 | send(remoteClient, (const char*)buf, c_welcomeMessageLength, 0); 168 | delete[] buf; 169 | } 170 | 171 | 172 | void mir_sdr_device::start(SOCKET client) 173 | { 174 | started = true; 175 | 176 | remoteClient = client; 177 | writeWelcomeString(); 178 | 179 | cout << endl << "Starting..." << endl; 180 | 181 | 182 | if (thrdRx != 0) // just in case.. 183 | { 184 | pthread_cancel(*thrdRx ); 185 | delete thrdRx; 186 | thrdRx = 0; 187 | } 188 | thrdRx = new pthread_t(); 189 | 190 | pthread_attr_t attr; 191 | pthread_attr_init(&attr); 192 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 193 | int res = pthread_create(thrdRx, &attr, &receive, this); 194 | pthread_attr_destroy(&attr); 195 | } 196 | 197 | BYTE* mir_sdr_device::mergeIQ(const short* idata, const short* qdata, int samplesPerPacket, int& buflen) 198 | { 199 | BYTE* buf = 0; 200 | buflen = 0; 201 | 202 | if (bitWidth == BITS_16) 203 | { 204 | buflen = samplesPerPacket *4; 205 | buf = new BYTE[buflen]; 206 | for (int i = 0, j = 0; i < samplesPerPacket; i++) 207 | { 208 | buf[j++] = (BYTE)(idata[i] & 0xff); 209 | buf[j++] = (BYTE)((idata[i] & 0xff00) >> 8); 210 | 211 | buf[j++] = (BYTE)(qdata[i] & 0xff); 212 | buf[j++] = (BYTE)((qdata[i] & 0xff00) >> 8); 213 | } 214 | } 215 | else if (bitWidth == BITS_8) 216 | { 217 | // assume the 14 Bit ADC values are mapped onto signed 16-Bit values covering the whole range 218 | buflen = samplesPerPacket * 2; 219 | buf = new BYTE[buflen]; 220 | for (int i = 0, j = 0; i < samplesPerPacket; i++) 221 | { 222 | //restore the unsigned 14-Bit signal 223 | int tmpi = (idata[i] >> 2) + 0x2000; 224 | int tmpq = (qdata[i] >> 2) + 0x2000; 225 | 226 | // cut the six low order bits 227 | tmpi >>= 6; 228 | tmpq >>= 6; 229 | 230 | buf[j++] = (BYTE)tmpi; 231 | buf[j++] = (BYTE)tmpq; 232 | //buf[j++] = (BYTE)(idata[i] / 64 + 127); 233 | //buf[j++] = (BYTE)(qdata[i] / 64 + 127); 234 | } 235 | } 236 | //else if (bitWidth == BITS_8) 237 | //{ 238 | // // assume the 12 Bit ADC values are mapped onto signed 16-Bit values covering the whole range 239 | // buflen = samplesPerPacket * 2; 240 | // buf = new BYTE[buflen]; 241 | // for (int i = 0, j = 0; i < samplesPerPacket; i++) 242 | // { 243 | // //restore the unsigned 12-Bit signal 244 | // int tmpi = (idata[i] >> 4) + 2048; 245 | // int tmpq = (qdata[i] >> 4) + 2048; 246 | 247 | // // cut the four low order bits 248 | // tmpi >>= 4; 249 | // tmpq >>= 4; 250 | 251 | // buf[j++] = (BYTE)tmpi; 252 | // buf[j++] = (BYTE)tmpq; 253 | // //buf[j++] = (BYTE)(idata[i] / 64 + 127); 254 | // //buf[j++] = (BYTE)(qdata[i] / 64 + 127); 255 | // } 256 | //} 257 | else if (bitWidth == BITS_4) 258 | { 259 | buflen = samplesPerPacket * 1; 260 | buf = new BYTE[buflen]; 261 | for (int i = 0, j = 0; i < samplesPerPacket; i++) 262 | { 263 | //I-Byte 264 | byte b = (BYTE)(idata[i] / 64 + 127); 265 | // Low order nibble 266 | byte b2 = b >> 4; 267 | b2 &= 0x0f; 268 | 269 | //Q-Byte 270 | b = (BYTE)(qdata[i] / 64 + 127); 271 | // High order nibble 272 | byte b3 = b & 0xf0; 273 | 274 | byte b4 = b2 | b3; 275 | buf[j++] = b4; 276 | } 277 | } 278 | return buf; 279 | } 280 | 281 | // 2048000 numSamples == 1344 282 | // 1000* 1344 * 1/2048000 = 656.25ms 283 | void streamCallback(short *xi, short *xq, unsigned int firstSampleNum, 284 | int grChanged, int rfChanged, int fsChanged, unsigned int numSamples, 285 | unsigned int reset, unsigned int hwRemoved, void *cbContext) 286 | { 287 | 288 | if (hwRemoved) 289 | { 290 | cout << " !!! HW removed !!!" << endl; 291 | return; 292 | } 293 | if (reset) 294 | { 295 | cout << " !!! reset !!!" << endl; 296 | return; 297 | } 298 | 299 | static int count = 0; 300 | 301 | mir_sdr_device* md = (mir_sdr_device*)cbContext; 302 | try 303 | { 304 | if (!md->isStreaming) 305 | { 306 | return; 307 | } 308 | //In case of a socket error, dont process the data for one second 309 | if (md->cbksPerSecond-- > 0) 310 | { 311 | if (!md->cbkTimerStarted) 312 | { 313 | md->cbkTimerStarted = true; 314 | cout << "Discarding samples for one second\n"; 315 | } 316 | return; 317 | } 318 | else if (md->cbkTimerStarted) 319 | { 320 | md->cbkTimerStarted = false; 321 | } 322 | if (md->remoteClient == INVALID_SOCKET) 323 | return; 324 | 325 | #ifdef TIME_MEAS 326 | count++; 327 | if (count % 1000 == 0) 328 | { 329 | QueryPerformanceCounter(&Count2); 330 | CMeasTimeDiff::formattedTimeOutput ("1000 sdrplay buffers (ms)", CMeasTimeDiff::calcTimeDiff_in_ms (Count2, Count1)); 331 | QueryPerformanceCounter(&Count1); 332 | } 333 | #endif 334 | int buflen = 0; 335 | BYTE* buf = md->mergeIQ(xi, xq, numSamples, buflen); 336 | int remaining = buflen; 337 | int sent = 0; 338 | while (remaining > 0) 339 | { 340 | fd_set writefds; 341 | struct timeval tv= {1,0}; 342 | FD_ZERO(&writefds); 343 | FD_SET(md->remoteClient, &writefds); 344 | int res = select(md->remoteClient+1, NULL, &writefds, NULL, &tv); 345 | if (res > 0) 346 | { 347 | sent = send(md->remoteClient, (const char*)buf + (buflen - remaining), remaining, 0); 348 | remaining -= sent; 349 | } 350 | else 351 | { 352 | md->cbksPerSecond = md->initialSamplingRateHz / numSamples; //1 sec "timer" in the error case. assumed this does not change frequently 353 | delete[] buf; 354 | throw msg_exception("socket error " + to_string(errno)); 355 | } 356 | } 357 | delete[] buf; 358 | } 359 | catch (exception& e) 360 | { 361 | cout << "Error in streaming callback :" << e.what() << endl; 362 | } 363 | } 364 | 365 | void gainChangeCallback(unsigned int gRdB, unsigned int lnaGRdB, void* cbContext) 366 | { 367 | // do nothing... 368 | } 369 | 370 | 371 | int getCommandAndValue(char* rxBuf, int& value) 372 | { 373 | BYTE valbuf[4]; 374 | int cmd = rxBuf[0]; 375 | memcpy( valbuf, rxBuf + 1,4); 376 | 377 | if (common::isLittleEndian()) 378 | value = valbuf[3] + valbuf[2] * 0x100 + valbuf[1] * 0x10000 + valbuf[0] * 0x1000000; 379 | else 380 | value = valbuf[0] + valbuf[1] * 0x100 + valbuf[2] * 0x10000 + valbuf[3] * 0x1000000; 381 | return cmd; 382 | } 383 | 384 | 385 | /// 386 | /// Receive thread, to process commands 387 | /// 388 | void* receive(void* p) 389 | { 390 | mir_sdr_ErrT err; 391 | mir_sdr_device* md = (mir_sdr_device*)p; 392 | cout << "**** receive thread entered. *****" << endl; 393 | /* 394 | pthread_mutex_lock(&md->mutex_rxThreadStarted); 395 | pthread_cond_signal(&md->started_cond); 396 | pthread_mutex_unlock(&md->mutex_rxThreadStarted); 397 | cout << "**** receive thread signalled. *****" << endl; 398 | */ 399 | try 400 | { 401 | float apiVersion = 0.0f; 402 | 403 | mir_sdr_ErrT errInit;// = md->stream_Uninit(); 404 | err = mir_sdr_ApiVersion(&apiVersion); 405 | 406 | cout << "\nmir_sdr_ApiVersion returned with: " << err << endl; 407 | cout << "API Version " << apiVersion << endl; 408 | 409 | md->initialSamplingRateHz = md->samplingConfigs[2].samplingRateHz; 410 | md->oldDeltaSrHz = 0; 411 | int smplsPerPacket; 412 | 413 | mir_sdr_SetGrModeT grMode = mir_sdr_USE_RSP_SET_GR; 414 | if (md->flatGr) 415 | { 416 | grMode = mir_sdr_USE_SET_GR; 417 | md->LNAstate = 0; 418 | } 419 | else 420 | { 421 | int gain = md->RequestedGain; 422 | if (!md->RSPGainValuesFromRequestedGain(gain, md->rxType, md->LNAstate, md->gainReduction)) 423 | { 424 | cout << "\nCannot retrieve LNA state and Gain Reduction from requested gain value " << gain << endl; 425 | cout << "Program cannot continue" << endl; 426 | return 0; 427 | } 428 | cout << "\n Using LNA State: " << md->LNAstate << endl; 429 | cout << " Using Gain Reduction: " << md->gainReduction << endl; 430 | } 431 | //// for tests 432 | //errInit = mir_sdr_SetTransferMode(mir_sdr_BULK); 433 | //cout << "\mir_sdr_SetTransferMode " << mir_sdr_BULK << " returned with: " << errInit << endl; 434 | 435 | 436 | secondChance: 437 | md->oldDeltaSrHz = 0; 438 | errInit = mir_sdr_StreamInit(&md->gainReduction, 439 | md->initialSamplingRateHz / 1e6, 440 | md->currentFrequencyHz / 1e6, 441 | md->samplingConfigs[2].bandwidth, 442 | mir_sdr_IF_Zero, 443 | md->LNAstate, 444 | &md->sys, 445 | grMode, 446 | &smplsPerPacket, 447 | streamCallback, 448 | gainChangeCallback, 449 | md); 450 | 451 | cout << "\nmir_sdr_StreamInit returned with: " << errInit << endl; 452 | // disable DC offset and IQ imbalance correction (default is for these to be enabled – this 453 | // just show how to disable if required) 454 | //err = mir_sdr_DCoffsetIQimbalanceControl(1, 0); 455 | //cout << "\nmir_sdr_DCoffsetIQimbalanceControl returned with: " << err << endl; 456 | 457 | if (errInit == mir_sdr_AlreadyInitialised) 458 | { 459 | cout << "Already initialized, uninit first" << endl; 460 | mir_sdr_ErrT errInit = md->stream_Uninit(); 461 | cout << "\stream_Uninit returned with: " << err << endl; 462 | usleep(1000000); 463 | goto secondChance; 464 | } 465 | if (errInit == mir_sdr_Success || errInit == mir_sdr_AlreadyInitialised) 466 | { 467 | cout << "Starting SDR streaming" << endl; 468 | md->isStreaming = true; 469 | } 470 | else 471 | { 472 | cout << "API Init failed with error: " << errInit << endl; 473 | md->isStreaming = false; 474 | } 475 | 476 | md->setAntenna(md->antenna); 477 | 478 | // configure DC tracking in tuner 479 | err = mir_sdr_SetDcMode(4, 1); // select one-shot tuner DC offset correction with speedup 480 | cout << "\nmir_sdr_SetDcMode returned with: " << err << endl; 481 | 482 | err = mir_sdr_SetDcTrackTime(63); // with maximum tracking time 483 | cout << "\nmir_sdr_SetDcTrackTime returned with: " << err << endl; 484 | md->setAGC(true); 485 | } 486 | catch (const std::exception& ) 487 | { 488 | cout << " !!!!!!!!! Exception in the initialization !!!!!!!!!!\n"; 489 | return 0; 490 | } 491 | 492 | try 493 | { 494 | char rxBuf[16]; 495 | for (;;) 496 | { 497 | const int cmd_length = 5; 498 | memset(rxBuf, 0, 16); 499 | int remaining = cmd_length; 500 | 501 | while (remaining > 0) 502 | { 503 | int rcvd = recv(md->remoteClient, rxBuf + (cmd_length - remaining), remaining, 0); //read 5 bytes (cmd + value) 504 | remaining -= rcvd; 505 | 506 | if (rcvd == 0) 507 | { 508 | err = mir_sdr_StreamUninit(); 509 | cout << "mir_sdr_StreamUninit returned with: " << err << endl; 510 | err = mir_sdr_ReleaseDeviceIdx(); 511 | cout << "mir_sdr_ReleaseDeviceIdx returned with: " << err << endl; 512 | throw msg_exception("Socket closed"); 513 | //err = mir_sdr_ReleaseDeviceIdx(); 514 | } 515 | if (rcvd == SOCKET_ERROR) 516 | { 517 | err = mir_sdr_StreamUninit(); 518 | cout << "mir_sdr_ReleaseDeviceIdx returned with: " << err << endl; 519 | err = mir_sdr_ReleaseDeviceIdx(); 520 | cout << "mir_sdr_StreamUninit returned with: " << err << endl; 521 | throw msg_exception("Socket error"); 522 | } 523 | } 524 | 525 | int value = 0; // out parameter 526 | int cmd = getCommandAndValue(rxBuf, value); 527 | 528 | // The ids of the commands are defined in rtl_tcp, the names had been inserted here 529 | // for better readability 530 | switch (cmd) 531 | { 532 | case mir_sdr_device::CMD_SET_FREQUENCY: //set frequency 533 | //value is freq in Hz 534 | err = md->setFrequency(value); 535 | break; 536 | 537 | case (int)mir_sdr_device::CMD_SET_SAMPLINGRATE: 538 | md->oldDeltaSrHz = 0; 539 | err = md->setSamplingRate(value);//value is sr in Hz 540 | break; 541 | 542 | case (int)mir_sdr_device::CMD_SET_FREQUENCYCORRECTION: //value is ppm correction 543 | md->setFrequencyCorrection(value); 544 | break; 545 | 546 | case (int)mir_sdr_device::CMD_SET_FREQUENCYCORRECTION_PPM10: //value is ppm*10 correction 547 | md->setFrequencyCorrection100(value); 548 | break; 549 | 550 | case (int)mir_sdr_device::CMD_SET_TUNER_GAIN_BY_INDEX: 551 | //value is gain value between 0 and 100 552 | err = md->setGain(value); 553 | break; 554 | 555 | case (int)mir_sdr_device::CMD_SET_AGC_MODE: 556 | err = md->setAGC(value != 0); 557 | break; 558 | 559 | case (int)mir_sdr_device::CMD_SET_BIAS_T: 560 | err = md->setBiasT(value != 0); 561 | break; 562 | 563 | case (int)mir_sdr_device::CMD_SET_RSP2_ANTENNA_CONTROL: 564 | md->setAntenna(value); 565 | break; 566 | default: 567 | printf("Unknown Command; 0x%x 0x%x 0x%x 0x%x 0x%x\n", 568 | rxBuf[0], rxBuf[1], rxBuf[2], rxBuf[3], rxBuf[4]); 569 | break; 570 | } 571 | } 572 | } 573 | catch (exception& e) 574 | { 575 | cout << "Error in receive :" << e.what() << endl; 576 | //err = mir_sdr_StreamUninit(); 577 | //cout << "mir_sdr_StreamUninit returned with: " << err << endl; 578 | //if (err == mir_sdr_Success) 579 | // cout << "StreamUnInit successful(0)" << endl; 580 | //else 581 | // cout << "StreamUnInit failed (1) with " << err << endl; 582 | } 583 | cout << "**** Rx thread terminating. ****" << endl; 584 | return 0; 585 | } 586 | 587 | //value is correction in ppm 588 | mir_sdr_ErrT mir_sdr_device::setFrequencyCorrection(int value) 589 | { 590 | mir_sdr_ErrT err = mir_sdr_SetPpm((double)value); 591 | 592 | cout << "\nmir_sdr_SetPpm returned with: " << err << endl; 593 | if (err != mir_sdr_Success) 594 | cout << "PPM setting error: " << err << endl; 595 | else 596 | cout << "PPM correction: " << value << endl; 597 | return err; 598 | } 599 | 600 | //value is correction in ppm*100 601 | mir_sdr_ErrT mir_sdr_device::setFrequencyCorrection100(int value) 602 | { 603 | double valPpm = (double)(value / 100.0); 604 | mir_sdr_ErrT err = mir_sdr_SetPpm(valPpm); 605 | 606 | cout << "\nmir_sdr_SetPpm returned with: " << err << endl; 607 | if (err != mir_sdr_Success) 608 | { 609 | cout << "PPM setting error: " << err << endl; 610 | return err; 611 | } 612 | else 613 | cout << "PPM correction: " << valPpm << endl; 614 | 615 | 616 | // first undo the old samplingrate delta 617 | if (oldDeltaSrHz != 0) 618 | { 619 | err = mir_sdr_SetFs(-oldDeltaSrHz, 0, 0, 0); 620 | cout << "\nmir_sdr_SetFs returned with: " << err << endl; 621 | if (err != mir_sdr_Success) 622 | { 623 | cout << "Undo old Sampling rate delta setting error: " << err << endl; 624 | } 625 | else 626 | cout << "old Sampling rate correction undone: " << -oldDeltaSrHz << "Hz" << endl << endl; 627 | } 628 | 629 | // necessary to let the sr settling 630 | usleep(100000.0f); 631 | 632 | double tmp = initialSamplingRateHz; 633 | double deltaSrHz =(-1)* initialSamplingRateHz * valPpm / 1e6; 634 | if (abs(deltaSrHz) <= DBL_EPSILON) 635 | return err; 636 | err = mir_sdr_SetFs(deltaSrHz, 0, 0, 0); 637 | cout << "\nmir_sdr_SetFs returned with: " << err << endl; 638 | if (err != mir_sdr_Success) 639 | { 640 | cout << "Sampling rate setting error: " << err << endl; 641 | } 642 | else 643 | cout << "Sampling rate correction: " << deltaSrHz << "Hz" << endl << endl; 644 | oldDeltaSrHz = deltaSrHz; 645 | 646 | return err; 647 | } 648 | 649 | mir_sdr_ErrT mir_sdr_device::setBiasT(int value) 650 | { 651 | mir_sdr_ErrT err = mir_sdr_Success; 652 | switch (rxType) 653 | { 654 | case RSP1A: 655 | err = mir_sdr_rsp1a_BiasT(value); 656 | break; 657 | case RSP2: 658 | err = mir_sdr_RSPII_BiasTControl(value); 659 | break; 660 | case RSPduo: 661 | err = mir_sdr_rspDuo_BiasT(value); 662 | break; 663 | default: 664 | break; 665 | } 666 | cout << "\nmir_sdr_xxx_BiasT returned with: " << err << endl; 667 | if (err != mir_sdr_Success) 668 | cout << "BiasT setting error: " << err << endl; 669 | else 670 | cout << "BiasT setting: " << value << endl; 671 | return err; 672 | } 673 | 674 | mir_sdr_ErrT mir_sdr_device::setAntenna(int value) 675 | { 676 | mir_sdr_ErrT err = mir_sdr_Success; 677 | switch (rxType) 678 | { 679 | case RSP1A: 680 | err = mir_sdr_HwVerError; 681 | break; 682 | case RSP2: 683 | err = mir_sdr_RSPII_AntennaControl((mir_sdr_RSPII_AntennaSelectT)value); 684 | break; 685 | case RSPduo: 686 | err = mir_sdr_rspDuo_TunerSel((mir_sdr_rspDuo_TunerSelT)(value-4)); 687 | break; 688 | default: 689 | break; 690 | } 691 | 692 | cout << "\nmir_sdr_RSPII_AntennaControl returned with: " << err << endl; 693 | if (err != mir_sdr_Success) 694 | cout << "Antenna Control Setting error: " << err << endl; 695 | else 696 | cout << "Antenna Control Setting: " << value << endl; 697 | return err; 698 | } 699 | 700 | mir_sdr_ErrT mir_sdr_device::setAGC(bool on) 701 | { 702 | mir_sdr_ErrT err = mir_sdr_Fail; 703 | if (on == false) 704 | { 705 | err = mir_sdr_AgcControl(mir_sdr_AGC_DISABLE, agcPoint_dBfs, 0, 0, 0, 0, LNAstate); 706 | if(VERBOSE) 707 | cout << "\nmir_sdr_AgcControl OFF returned with: " << err << endl; 708 | } 709 | else 710 | { 711 | // enable AGC with a setPoint of -15dBfs //optimum for DAB 712 | err = mir_sdr_AgcControl(mir_sdr_AGC_50HZ, agcPoint_dBfs, 0, 0, 0, 0, LNAstate); 713 | if(VERBOSE) 714 | cout << "\nmir_sdr_AgcControl 50Hz, " << agcPoint_dBfs << " dBfs returned with: " << err << endl; 715 | } 716 | if (err != mir_sdr_Success) 717 | { 718 | cout << "SetAGC failed." << endl; 719 | } 720 | 721 | return err; 722 | } 723 | 724 | bool mir_sdr_device::RSPGainValuesFromRequestedGain(int flatValue, int rxtype, int& LNAstate, int& gr) 725 | { 726 | if (flatGr) 727 | return false; 728 | 729 | mir_sdr_SetGrModeT grMode = mir_sdr_USE_RSP_SET_GR; 730 | 731 | mir_sdr_BandT band = (mir_sdr_BandT)0; 732 | int gRdB = 0; 733 | int gRdBsystem = 0; 734 | 735 | mir_sdr_ErrT err = mir_sdr_GetGrByFreq(currentFrequencyHz / 1e6, &band, &gRdB, LNAstate, 736 | &gRdBsystem, grMode); 737 | 738 | gainConfiguration gcfg(band); 739 | 740 | if (gcfg.calculateGrValues(flatValue, rxType, LNAstate, gr)) 741 | { 742 | return true; 743 | } 744 | return false; 745 | } 746 | 747 | mir_sdr_ErrT mir_sdr_device::setGain(int value) 748 | { 749 | mir_sdr_ErrT err; 750 | mir_sdr_SetGrModeT grMode; 751 | 752 | if (flatGr) 753 | { 754 | grMode = mir_sdr_USE_SET_GR; 755 | gainReduction = gainConfiguration::GAIN_STEPS - value; 756 | err = mir_sdr_SetGr(gainReduction, 1, 0); 757 | } 758 | else 759 | { 760 | 761 | int lnastate = 0; 762 | int gr = 0; 763 | 764 | if (RSPGainValuesFromRequestedGain(value, rxType, lnastate, gr)) 765 | { 766 | err = mir_sdr_RSP_SetGr(gr, lnastate, 1, 0); 767 | gainReduction = gr; 768 | LNAstate = lnastate; 769 | 770 | if (VERBOSE) 771 | { 772 | cout << "RSP_SetGr succeeded with requested value: " << gainConfiguration::GAIN_STEPS - value << endl; 773 | cout << "LNA State: " << lnastate << endl; 774 | cout << "Gr value: " << gr << endl; 775 | } 776 | return err; 777 | } 778 | else 779 | { 780 | cout << "RSP_SetGr failed with requested value: " << gainConfiguration::GAIN_STEPS -value << endl; 781 | return (mir_sdr_ErrT) -1; 782 | } 783 | } 784 | 785 | if (VERBOSE) 786 | cout << "\nmir_sdr_SetGr returned with: " << err << endl; 787 | 788 | if (err != mir_sdr_Success) 789 | { 790 | cout << "SetGr failed with requested value: " << gainConfiguration::GAIN_STEPS -value << endl; 791 | } 792 | else 793 | cout << "SetGr succeeded with requested value: " << gainConfiguration::GAIN_STEPS -value << endl; 794 | 795 | return err; 796 | } 797 | 798 | mir_sdr_ErrT mir_sdr_device::setSamplingRate(int requestedSrHz) 799 | { 800 | mir_sdr_ErrT err = stream_Uninit(); 801 | if (err != mir_sdr_Success) 802 | return err; 803 | 804 | int ix = getSamplingConfigurationTableIndex(requestedSrHz); 805 | if (ix >= 0) 806 | { 807 | err = stream_InitForSamplingRate(ix); 808 | return err; 809 | } 810 | else 811 | { 812 | 813 | } 814 | return mir_sdr_Fail; 815 | } 816 | 817 | mir_sdr_ErrT mir_sdr_device::setFrequency(int valueHz) 818 | { 819 | mir_sdr_ErrT err = mir_sdr_SetRf((double)valueHz, 1, 0); 820 | if (VERBOSE) 821 | cout << "\nmir_sdr_SetRf returned with: " << err << endl; 822 | 823 | switch (err) 824 | { 825 | case mir_sdr_Success: 826 | break; 827 | case mir_sdr_RfUpdateError: 828 | //sleep(0.5f);//wait for the old command to settle 829 | err = mir_sdr_SetRf((double)valueHz, 1, 0); 830 | if (VERBOSE) 831 | { 832 | cout << "\nmir_sdr_SetRf returned with: " << err << endl; 833 | cout << "Frequency setting result: " << err << endl; 834 | } 835 | 836 | if (err == mir_sdr_OutOfRange || mir_sdr_RfUpdateError) 837 | err = reinit_Frequency(valueHz); 838 | break; 839 | 840 | case mir_sdr_OutOfRange: 841 | err = reinit_Frequency(valueHz); 842 | break; 843 | default: 844 | break; 845 | } 846 | if (err != mir_sdr_Success) 847 | { 848 | cout << "Frequency setting error: " << err << endl; 849 | cout << "Requested Frequency was: " << +valueHz << endl; 850 | } 851 | else 852 | { 853 | currentFrequencyHz = valueHz; 854 | if (VERBOSE) 855 | cout << "Frequency set to (Hz): " << valueHz << endl; 856 | } 857 | return err; 858 | } 859 | 860 | mir_sdr_ErrT mir_sdr_device::reinit_Frequency(int valueHz) 861 | { 862 | mir_sdr_ErrT err = mir_sdr_Fail; 863 | 864 | int samplesPerPacket; 865 | 866 | mir_sdr_SetGrModeT grMode; 867 | if (flatGr) 868 | grMode = mir_sdr_USE_SET_GR; 869 | else 870 | grMode = mir_sdr_USE_RSP_SET_GR; 871 | 872 | 873 | oldDeltaSrHz = 0; 874 | 875 | err = mir_sdr_Reinit( 876 | &gainReduction, 877 | initialSamplingRateHz / 1e6, 878 | (double)valueHz / 1e6, 879 | (mir_sdr_Bw_MHzT)0,//mir_sdr_Bw_MHzT.mir_sdr_BW_1_536, 880 | (mir_sdr_If_kHzT)0,//mir_sdr_If_kHzT.mir_sdr_IF_Zero, 881 | (mir_sdr_LoModeT)0,//mir_sdr_LoModeT.mir_sdr_LO_Undefined, 882 | LNAstate, 883 | &sys, 884 | grMode, 885 | &samplesPerPacket, 886 | mir_sdr_CHANGE_RF_FREQ); 887 | if (VERBOSE) 888 | cout << "\nmir_sdr_Reinit returned with: " << err << endl; 889 | if (err != mir_sdr_Success) 890 | { 891 | cout << "Requested Frequency (Hz) was: " << valueHz << endl; 892 | } 893 | else 894 | { 895 | if (VERBOSE) 896 | cout << "Frequency set to (Hz): " << valueHz << endl; 897 | currentFrequencyHz = valueHz; 898 | } 899 | return err; 900 | } 901 | 902 | //mir_sdr_ErrT mir_sdr_device::stream_InitForSamplingRate(int srHz) 903 | //{ 904 | // mir_sdr_Bw_MHzT bandwidth = srHz; 905 | // int reqSamplingRateHz = samplingConfigs[ix].samplingRateHz; 906 | // int deviceSamplingRateHz = samplingConfigs[ix].deviceSamplingRateHz; 907 | // unsigned int decimationFactor = samplingConfigs[ix].decimationFactor; 908 | // unsigned int doDecimation = samplingConfigs[ix].doDecimation ? 1 : 0; 909 | // return stream_InitForSamplingRate(bandwidth, reqSamplingRateHz, deviceSamplingRateHz, decimationFactor, doDecimation); 910 | //} 911 | mir_sdr_ErrT mir_sdr_device::stream_InitForSamplingRate(int sampleConfigsTableIndex) 912 | { 913 | oldDeltaSrHz = 0; 914 | int ix = sampleConfigsTableIndex; 915 | 916 | mir_sdr_Bw_MHzT bandwidth = samplingConfigs[ix].bandwidth; 917 | int reqSamplingRateHz = samplingConfigs[ix].samplingRateHz; 918 | int deviceSamplingRateHz = samplingConfigs[ix].deviceSamplingRateHz; 919 | unsigned int decimationFactor = samplingConfigs[ix].decimationFactor; 920 | unsigned int doDecimation = samplingConfigs[ix].doDecimation ? 1 : 0; 921 | return stream_InitForSamplingRate(bandwidth, reqSamplingRateHz, deviceSamplingRateHz, decimationFactor, doDecimation); 922 | } 923 | 924 | mir_sdr_ErrT mir_sdr_device::stream_InitForSamplingRate( 925 | mir_sdr_Bw_MHzT bandwidth, 926 | int reqSamplingRateHz, 927 | int deviceSamplingRateHz, 928 | unsigned int decimationFactor, 929 | unsigned int doDecimation 930 | ) 931 | { 932 | //int ix = sampleConfigsTableIndex; 933 | 934 | //mir_sdr_Bw_MHzT bandwidth = samplingConfigs[ix].bandwidth; 935 | //int reqSamplingRateHz = samplingConfigs[ix].samplingRateHz; 936 | //int deviceSamplingRateHz = samplingConfigs[ix].deviceSamplingRateHz; 937 | //unsigned int decimationFactor = samplingConfigs[ix].decimationFactor; 938 | //unsigned int doDecimation = samplingConfigs[ix].doDecimation ? 1 : 0; 939 | 940 | oldDeltaSrHz = 0; 941 | mir_sdr_ErrT err = mir_sdr_Fail; 942 | 943 | int samplesPerPacket; 944 | 945 | mir_sdr_SetGrModeT grMode; 946 | if (flatGr) 947 | grMode = mir_sdr_USE_SET_GR; 948 | else 949 | grMode = mir_sdr_USE_RSP_SET_GR; 950 | 951 | err = mir_sdr_StreamInit( 952 | &gainReduction, 953 | (double)deviceSamplingRateHz / 1e6, 954 | currentFrequencyHz / 1e6, 955 | bandwidth, 956 | mir_sdr_IF_Zero, 957 | LNAstate, 958 | &sys, 959 | grMode, 960 | &samplesPerPacket, 961 | streamCallback, 962 | gainChangeCallback, 963 | this); 964 | if (VERBOSE) 965 | cout << "\nmir_sdr_StreamInit returned with: " << err << endl; 966 | if (err != mir_sdr_Success) 967 | { 968 | cout << "Sampling Rate setting error: " << err << endl; 969 | cout << "Requested Sampling Rate was: " << reqSamplingRateHz << endl; 970 | } 971 | else 972 | { 973 | cout << "Sampling Rate set to (Hz): " << deviceSamplingRateHz << endl; 974 | initialSamplingRateHz = deviceSamplingRateHz; 975 | 976 | if (doDecimation == 1) 977 | { 978 | err = mir_sdr_DecimateControl(doDecimation, decimationFactor, 0); 979 | cout << "mir_sdr_DecimateControl returned with: " << err << endl; 980 | if (err != mir_sdr_Success) 981 | { 982 | cout << "Requested Decimation Factor was: " << decimationFactor << endl; 983 | } 984 | else 985 | { 986 | cout << "Decimation Factor set to " << decimationFactor << endl; 987 | } 988 | 989 | } 990 | else 991 | cout << "No Decimation applied\n"; 992 | } 993 | return err; 994 | } 995 | 996 | mir_sdr_ErrT mir_sdr_device::stream_Uninit() 997 | { 998 | mir_sdr_ErrT err = mir_sdr_Fail; 999 | int cnt = 0; 1000 | while (err != mir_sdr_Success) 1001 | { 1002 | cnt++; 1003 | try { 1004 | err = mir_sdr_StreamUninit(); 1005 | } 1006 | catch (...) 1007 | { 1008 | cout << "\nmir_sdr_StreamUninit returned with: " << err << endl; 1009 | err = mir_sdr_Fail; 1010 | } 1011 | if (err == mir_sdr_Success) 1012 | break; 1013 | usleep(100000.0f); 1014 | if (cnt == 5) 1015 | break; 1016 | } 1017 | if (err != mir_sdr_Success) 1018 | { 1019 | cout << "StreamUninit failed with: " << err << endl; 1020 | } 1021 | return err; 1022 | } 1023 | 1024 | /// 1025 | /// Gets the config table index for a requested sampling rate 1026 | /// 1027 | /// Requested sampling rate in Hz 1028 | /// Index into the samplingConfigs table, -1 if not found 1029 | int mir_sdr_device::getSamplingConfigurationTableIndex(int requestedSrHz) 1030 | { 1031 | for (int i = 0; i < c_numSamplingConfigs; i++) 1032 | { 1033 | samplingConfiguration sc = samplingConfigs[i]; 1034 | if (requestedSrHz == sc.samplingRateHz) 1035 | { 1036 | return i; 1037 | } 1038 | } 1039 | printf("Sampling Rate: %d; Should be %d or %d or %d or %d or %d\n", requestedSrHz, samplingConfigs[0].samplingRateHz, 1040 | samplingConfigs[1].samplingRateHz, samplingConfigs[2].samplingRateHz, samplingConfigs[3].samplingRateHz, samplingConfigs[4].samplingRateHz); 1041 | printf("Sampling Rate: %d Hz will be tried\n", requestedSrHz); 1042 | 1043 | return -1; 1044 | } 1045 | 1046 | 1047 | 1048 | -------------------------------------------------------------------------------- /rsp_tcp/mir_sdr_device.h: -------------------------------------------------------------------------------- 1 | /** 2 | ** RSP_tcp - TCP/IP I/Q Data Server for the sdrplay RSP2 3 | ** Copyright (C) 2017 Clem Schmidt, softsyst GmbH, http://www.softsyst.com 4 | ** 5 | ** This program is free software; you can redistribute it and/or modify 6 | ** it under the terms of the GNU General Public License as published by 7 | ** the Free Software Foundation; either version 2 of the License, or 8 | ** (at your option) any later version. 9 | ** 10 | ** This program is distributed in the hope that it will be useful, 11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ** GNU General Public License for more details. 14 | ** 15 | ** You should have received a copy of the GNU General Public License 16 | ** along with this program; if not, write to the Free Software 17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | ** 19 | **/ 20 | 21 | #pragma once 22 | #include "rsp_tcp.h" 23 | #include "common.h" 24 | #include "IPAddress.h" 25 | #include "mir_sdr.h" 26 | #include "rsp_cmdLineArgs.h" 27 | //#include "controlThread.h" 28 | #define HAVE_STRUCT_TIMESPEC 29 | #include 30 | #ifdef _WIN32 31 | #define sleep(n) Sleep(n*1000) 32 | #define usleep(n) Sleep(n/1000) 33 | #else 34 | #include //memset etc. 35 | #include 36 | #endif 37 | using namespace std; 38 | 39 | void* receive(void* md); 40 | void streamCallback(short *xi, short *xq, unsigned int firstSampleNum, 41 | int grChanged, int rfChanged, int fsChanged, unsigned int numSamples, 42 | unsigned int reset, unsigned int hwRemoved, void *cbContext); 43 | 44 | void gainChangeCallback(unsigned int gRdB, unsigned int lnaGRdB, void* cbContext); 45 | 46 | struct samplingConfiguration 47 | { 48 | const int samplingRateHz; 49 | const int deviceSamplingRateHz; 50 | const mir_sdr_Bw_MHzT bandwidth; 51 | const int decimationFactor; 52 | const bool doDecimation; 53 | 54 | samplingConfiguration(int srHz, int devSrHz, mir_sdr_Bw_MHzT bw, int decimFact, bool doDecim) 55 | : samplingRateHz(srHz), 56 | deviceSamplingRateHz(devSrHz), 57 | bandwidth(bw), 58 | decimationFactor(decimFact), 59 | doDecimation(doDecim) 60 | { 61 | } 62 | }; 63 | 64 | typedef struct 65 | { 66 | void *dev; 67 | int port; 68 | int wait; 69 | const char *addr; 70 | bool* pDoExit; 71 | } 72 | ctrl_thread_data_t; 73 | void *ctrl_thread_fn(void *arg); 74 | 75 | 76 | class mir_sdr_device 77 | { 78 | public: 79 | mir_sdr_device(); 80 | ~mir_sdr_device(); 81 | 82 | private: 83 | int getSamplingConfigurationTableIndex(int requestedSrHz); 84 | void writeWelcomeString() const; 85 | void cleanup(); 86 | 87 | friend void* receive(void* p); 88 | friend void streamCallback(short *xi, short *xq, unsigned int firstSampleNum, 89 | int grChanged, int rfChanged, int fsChanged, unsigned int numSamples, 90 | unsigned int reset, unsigned int hwRemoved, void *cbContext); 91 | 92 | public: 93 | void init(rsp_cmdLineArgs* pargs); 94 | void start(SOCKET client); 95 | void stop(); 96 | void createCtrlThread(const char* addr, int port); 97 | 98 | pthread_mutex_t mutex_rxThreadStarted; 99 | pthread_cond_t started_cond = PTHREAD_COND_INITIALIZER; 100 | pthread_t* thrdRx; 101 | pthread_t* thrdCtrl; 102 | ctrl_thread_data_t ctrlThreadData; 103 | bool ctrlThreadExitFlag = false; 104 | 105 | /// 106 | /// API: Device Enumeration Structure 107 | /// 108 | string serno; // serial number 109 | string DevNm; // device string (USB) 110 | BYTE hwVer; // HW version 111 | bool devAvail; // true if available 112 | bool isStreaming; 113 | bool flatGr; // true: dont use the gain reduction tables 114 | int LNAstate; // Calculated from the RequestedGain 115 | 116 | int RequestedGain; // the gain requested from the user, NOT the gain reduction used by the RSP 117 | bool started = false; 118 | unsigned int DeviceIndex; 119 | //The socket of the remote app 120 | SOCKET remoteClient; 121 | bool VERBOSE = false; 122 | 123 | 124 | 125 | private: 126 | 127 | const int c_welcomeMessageLength = 100; 128 | BYTE* mergeIQ(const short* idata, const short* qdata, int samplesPerPacket, int& buflen); 129 | mir_sdr_ErrT setFrequencyCorrection(int value); 130 | mir_sdr_ErrT setFrequencyCorrection100(int value); 131 | mir_sdr_ErrT setBiasT(int value); 132 | mir_sdr_ErrT setAntenna(int value); 133 | mir_sdr_ErrT setAGC(bool on); 134 | mir_sdr_ErrT setGain(int value); 135 | mir_sdr_ErrT setSamplingRate(int requestedSrHz); 136 | mir_sdr_ErrT setFrequency(int valueHz); 137 | mir_sdr_ErrT reinit_Frequency(int valueHz); 138 | mir_sdr_ErrT stream_InitForSamplingRate(int sampleConfigsTableIndex); 139 | mir_sdr_ErrT mir_sdr_device::stream_InitForSamplingRate( 140 | mir_sdr_Bw_MHzT bandwidth, 141 | int reqSamplingRateHz, 142 | int deviceSamplingRateHz, 143 | unsigned int decimationFactor, 144 | unsigned int doDecimation 145 | ); 146 | mir_sdr_ErrT stream_Uninit(); 147 | bool RSPGainValuesFromRequestedGain(int flatValue, int rxtype, int& LNAstate, int& gr); 148 | 149 | //Reference: rtl_tcp.c fct command_worker, line 277 150 | //Copied from QIRX 151 | enum eRTLCommands 152 | { 153 | CMD_SET_FREQUENCY = 1 154 | , CMD_SET_SAMPLINGRATE = 2 155 | , CMD_SET_GAIN_MODE = 3 //int manual 156 | , CMD_SET_GAIN = 4 //int gain, tenth dB; fct tuner_r82xx.c fct r82xx_set_gain 157 | , CMD_SET_FREQUENCYCORRECTION = 5 //int ppm 158 | , CMD_SET_IF_GAIN = 6 //int stage, int gain 159 | , CMD_SET_AGC_MODE = 8 //int on 160 | , CMD_SET_DIRECT_SAMPLING = 9 //int on 161 | , CMD_SET_OFFSET_TUNING = 10 //int on 162 | , CMD_SET_TUNER_GAIN_BY_INDEX = 13 163 | , CMD_SET_BIAS_T = 14 //int on 164 | , CMD_SET_RSP2_ANTENNA_CONTROL = 33 //int Antenna Select 165 | , CMD_SET_FREQUENCYCORRECTION_PPM10 = 0x4a //int ppm * 10 166 | }; 167 | 168 | // This server is able to stream native 16-bit data (of "short" type) 169 | // or - for comaptibility with some apps, 8-bit data, 170 | // where ( 8-bit Byte) = ( 16-bit short /64) + 127 171 | eBitWidth bitWidth = BITS_16; 172 | 173 | // Reasonable number of possible bandwidth/sampling rate combinations 174 | const int c_numSamplingConfigs = 10; 175 | samplingConfiguration samplingConfigs[10] = { 176 | samplingConfiguration(512000, 2048000, mir_sdr_BW_0_300, 4, true), 177 | samplingConfiguration(1024000, 2048000, mir_sdr_BW_0_600, 2, true), 178 | samplingConfiguration(2048000, 2048000, mir_sdr_BW_1_536, 1, false), 179 | samplingConfiguration(4096000, 4096000, mir_sdr_BW_5_000, 1, false), 180 | samplingConfiguration(8192000, 8192000, mir_sdr_BW_8_000, 1, false), 181 | samplingConfiguration(3000000, 3000000, mir_sdr_BW_1_536, 1, false), 182 | samplingConfiguration(4000000, 4000000, mir_sdr_BW_1_536, 1, false), 183 | samplingConfiguration(2400000, 2400000, mir_sdr_BW_1_536, 1, false), 184 | samplingConfiguration(2500000, 2500000, mir_sdr_BW_1_536, 1, false), 185 | samplingConfiguration(2000000, 8000000, mir_sdr_BW_8_000, 4, true) 186 | }; 187 | 188 | 189 | //QIRX internal type for the RSP2 190 | eRxType rxType;// 7 for RSP1, 8 for RSP2 191 | 192 | //Generic API error type 193 | mir_sdr_ErrT err; 194 | 195 | int sys = 40; 196 | int agcPoint_dBfs = -25; 197 | 198 | // currently commanded values 199 | int currentFrequencyHz; 200 | int gainReduction; // Calculated from the RequestedGain 201 | double initialSamplingRateHz; 202 | double oldDeltaSrHz; 203 | int antenna = 5; 204 | int amPort = 0; 205 | 206 | //Callbacks per second, for a "timer" to discard samples 207 | //to prevent overrun in the device in the error case 208 | int cbksPerSecond = 0; 209 | bool cbkTimerStarted = false; 210 | }; 211 | 212 | -------------------------------------------------------------------------------- /rsp_tcp/rsp_cmdLineArgs.cpp: -------------------------------------------------------------------------------- 1 | //https://devblogs.microsoft.com/cppblog/standards-version-switches-in-the-compiler/#c++14 2 | /** 3 | ** RSP_tcp - TCP/IP I/Q Data Server for the sdrplay RSP2 4 | ** Copyright (C) 2017 Clem Schmidt, softsyst GmbH, http://www.softsyst.com 5 | ** 6 | ** This program is free software; you can redistribute it and/or modify 7 | ** it under the terms of the GNU General Public License as published by 8 | ** the Free Software Foundation; either version 2 of the License, or 9 | ** (at your option) any later version. 10 | ** 11 | ** This program is distributed in the hope that it will be useful, 12 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | ** GNU General Public License for more details. 15 | ** 16 | ** You should have received a copy of the GNU General Public License 17 | ** along with this program; if not, write to the Free Software 18 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 | ** 20 | **/ 21 | 22 | #include 23 | #include "IPAddress.h" 24 | #include "rsp_cmdLineArgs.h" 25 | #include "common.h" 26 | #include 27 | 28 | 29 | rsp_cmdLineArgs::rsp_cmdLineArgs(int argc, char** argv) 30 | { 31 | this->argc = argc; 32 | this->argv = argv; 33 | for (int i = 0; i < argc; i++) 34 | { 35 | string s = argv[i]; 36 | int len = s.length(); 37 | if (len == 2 && s[0] == '-') 38 | { 39 | selectors[s[1]] = i; 40 | } 41 | } 42 | } 43 | 44 | 45 | rsp_cmdLineArgs::~rsp_cmdLineArgs() 46 | { 47 | } 48 | 49 | int rsp_cmdLineArgs::intValue(int index, string error, int minval, int maxval) 50 | { 51 | int val; 52 | if (argc > index + 1) 53 | { 54 | string s = argv[index + 1]; 55 | try 56 | { 57 | val = std::stoi(s); 58 | if (!common::checkRange(val, minval, maxval)) 59 | throw msg_exception("Out of Range Error"); 60 | return val; 61 | } 62 | catch (exception& ) 63 | { 64 | std::cout << error << val << endl << endl; 65 | } 66 | } 67 | else 68 | std::cout << "Missing Argument" << endl << endl; 69 | return -1; 70 | } 71 | 72 | IPAddress* rsp_cmdLineArgs::ipAddValue( int index, string error) 73 | { 74 | IPAddress* ipadd = 0; 75 | if (argc > index + 1) 76 | { 77 | string s = argv[index + 1]; 78 | ipadd = new IPAddress(s); 79 | if (ipadd->sIPAddress == s) // then parse was ok 80 | return ipadd; 81 | else 82 | std::cout << error << s << endl << endl; 83 | } 84 | else 85 | std::cout << "Missing Argument" << endl << endl; 86 | return 0; 87 | } 88 | 89 | void rsp_cmdLineArgs::displayUsage() 90 | { 91 | cout << "Usage: \t[-a listen address, default is 127.0.0.1]" << endl; 92 | cout << "\t[-p listen port, default is 7890]" << endl; 93 | cout << "\t[-f frequency [Hz], default is 178352000Hz]" << endl; 94 | cout << "\t[-s sampling rate [Hz], allowed values are 512000, 1024000, 2048000, 4096000, 8192000, default is 2048000]" << endl; 95 | cout << "\t[-g gain value, initial value betwee 20 and 80, default is 25]" << endl; 96 | cout << "\t[-W bit width, value of 1 means 8 bit, value of 2 means 16 bit, default is 16 bit]" << endl; 97 | cout << "\t[-d device index, value counts from 0 to number of devices -1, default is 0]" << endl; 98 | cout << "\t[-T antenna, value of 1 means Antenna A, value of 2 means Antenna B, default is Antenn A]" << endl; 99 | cout << "\t[-v verbose mode, outputs many values on the command line window]" << endl; 100 | cout << "\t[-H High Impedance antenna port on RSP2 or RSPduo, 1 on, 0 off]" << endl; 101 | } 102 | 103 | 104 | 105 | int rsp_cmdLineArgs::parse() 106 | { 107 | map::iterator it; 108 | if (argc == 2 && argv[1][0] == '?') 109 | goto exit; 110 | 111 | for (it = selectors.begin(); it != selectors.end(); it++) 112 | { 113 | IPAddress* ipa = 0; 114 | switch (it->first) //key 115 | { 116 | case 's': 117 | SamplingRate = intValue(it->second, "Invalid Sampling Rate ", 512000, 8192000); 118 | if (SamplingRate == -1) 119 | goto exit; 120 | break; 121 | case 'p': 122 | Port = intValue(it->second, "Invalid Port Number ", 0, 0xffff); 123 | if (Port == -1) 124 | goto exit; 125 | break; 126 | case 'f': 127 | Frequency = intValue(it->second, "Invalid Frequency ", 0, 0x7fffffff); 128 | if (Frequency == -1) 129 | goto exit; 130 | break; 131 | case 'g': 132 | Gain = intValue(it->second, "Invalid Gain ", 0, 99); 133 | if (Gain == -1) 134 | goto exit; 135 | break; 136 | case 'W': 137 | BitWidth = intValue(it->second, "Invalid Bit Width ", 0, 2); 138 | if (BitWidth == -1) 139 | goto exit; 140 | break; 141 | case 'a': 142 | ipa = ipAddValue(it->second, "Invalid IP Address "); 143 | if (ipa == 0) 144 | goto exit; 145 | Address = *ipa; 146 | break; 147 | case 'v': 148 | verbose = intValue(it->second, "Invalid verbose value ", 0, 1); 149 | if (verbose == -1) 150 | goto exit; 151 | break; 152 | case 'H': 153 | amPort = intValue(it->second, "Invalid Antenna Value ", 0, 1); 154 | break; 155 | case 'T': 156 | Antenna = static_cast(intValue(it->second, "Invalid Antenna Value ", 1, 2) + 4); 157 | break; 158 | case 'd': 159 | requestedDeviceIndex = intValue(it->second, "Invalid Device Index requested ", 0, 8); 160 | if (requestedDeviceIndex == -1) 161 | goto exit; 162 | break; 163 | case 'h': 164 | goto exit; 165 | case '?': 166 | goto exit; 167 | default: 168 | cout << "Invalid argument -" + it->second; 169 | goto exit; 170 | 171 | } 172 | } 173 | return 0; 174 | exit: 175 | return -1; 176 | } -------------------------------------------------------------------------------- /rsp_tcp/rsp_cmdLineArgs.h: -------------------------------------------------------------------------------- 1 | /** 2 | ** RSP_tcp - TCP/IP I/Q Data Server for the sdrplay RSP2 3 | ** Copyright (C) 2017 Clem Schmidt, softsyst GmbH, http://www.softsyst.com 4 | ** 5 | ** This program is free software; you can redistribute it and/or modify 6 | ** it under the terms of the GNU General Public License as published by 7 | ** the Free Software Foundation; either version 2 of the License, or 8 | ** (at your option) any later version. 9 | ** 10 | ** This program is distributed in the hope that it will be useful, 11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ** GNU General Public License for more details. 14 | ** 15 | ** You should have received a copy of the GNU General Public License 16 | ** along with this program; if not, write to the Free Software 17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | ** 19 | **/ 20 | 21 | #pragma once 22 | #include 23 | #include 24 | #include "mir_sdr.h" 25 | #include "IPAddress.h" 26 | using namespace std; 27 | 28 | class rsp_cmdLineArgs 29 | { 30 | private: 31 | rsp_cmdLineArgs(){} 32 | int argc; 33 | char** argv; 34 | 35 | map < char, int> selectors; 36 | int intValue(int index, string error, int minval, int maxval); 37 | IPAddress* ipAddValue(int index, string error); 38 | 39 | public: 40 | IPAddress Address{ 127,0,0,1 }; 41 | int Port = 7890; 42 | int Frequency = 178352000; 43 | 44 | //This is the requested Gain value, not the GainReduction value 45 | int Gain = 25; 46 | int SamplingRate = 2048000; 47 | int BitWidth = 2; //16 Bit 48 | mir_sdr_RSPII_AntennaSelectT Antenna = mir_sdr_RSPII_ANTENNA_A; 49 | int requestedDeviceIndex = 0; 50 | int verbose = 0; 51 | int amPort = 0; 52 | 53 | rsp_cmdLineArgs(int argc, char** argv); 54 | int parse(); 55 | virtual ~rsp_cmdLineArgs(); 56 | static void displayUsage(); 57 | 58 | }; 59 | 60 | -------------------------------------------------------------------------------- /rsp_tcp/rsp_tcp.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | ** RSP_tcp - TCP/IP I/Q Data Server for the sdrplay RSP2 3 | ** Copyright (C) 2017 Clem Schmidt, softsyst GmbH, http://www.softsyst.com 4 | ** 5 | ** This program is free software; you can redistribute it and/or modify 6 | ** it under the terms of the GNU General Public License as published by 7 | ** the Free Software Foundation; either version 2 of the License, or 8 | ** (at your option) any later version. 9 | ** 10 | ** This program is distributed in the hope that it will be useful, 11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ** GNU General Public License for more details. 14 | ** 15 | ** You should have received a copy of the GNU General Public License 16 | ** along with this program; if not, write to the Free Software 17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | ** 19 | **/ 20 | 21 | /** 22 | ** The interface and the mirics API Library is Copyright SDRplay Ltd. 23 | ** For the sdrplay Copyright, see the file 24 | 25 | SDRplay_RSP_API_Release_Notes_V2.13.pdf 26 | 27 | **/ 28 | 29 | #include 30 | #include 31 | #include "common.h" 32 | #include "rsp_tcp.h" 33 | #include "rsp_cmdLineArgs.h" 34 | #include "devices.h" 35 | #include "sdrGainTable.h" 36 | #include "syTwoDimArray.h" 37 | #ifndef _WIN32 38 | #include 39 | #endif 40 | using namespace std; 41 | 42 | // V0.9.8 Sampling rate 2.000 for ADS-B 43 | // V0.9.10 Bitwidth 8 Bit corrected 44 | // VERBOSE output removable 45 | // sleep in Set Frequency removed 46 | // V0.9.12 PPM correction in hundreths units 47 | // V0.9.13 -H Cmdline Param : AM Port on/off (1/0) : Call before init 48 | string Version = "0.9.13"; 49 | 50 | map returnErrorStrings = 51 | { 52 | { E_OK, "OK"} 53 | ,{ E_PARAMETER, "Starting Parameter Error"} 54 | ,{ E_WRONG_API_VERSION, "Wrong or incompatible sdrplay API Version. Must be at least 2.13 and less than 3."} 55 | ,{ E_NO_DEVICE, "No sdrplay device found."} 56 | ,{ E_DEVICE_INDEX, "Requested Device Index not present: "} 57 | ,{ E_WIN_WSA_STARTUP, "WSAStartup failed with error: "} 58 | }; 59 | 60 | #ifdef _WIN32 61 | BOOL CtrlHandler(DWORD fdwCtrlType) 62 | { 63 | switch (fdwCtrlType) 64 | { 65 | // Handle the CTRL-C signal only. 66 | case CTRL_C_EVENT: 67 | printf("Shutdown by ctrl-c\n\n"); 68 | devices::instance().Stop(); 69 | exit(0); 70 | /* 71 | // CTRL-CLOSE: confirm that the user wants to exit. 72 | case CTRL_CLOSE_EVENT: 73 | Beep(600, 200); 74 | printf("Ctrl-Close event\n\n"); 75 | return(TRUE); 76 | 77 | // Pass other signals to the next handler. 78 | case CTRL_BREAK_EVENT: 79 | Beep(900, 200); 80 | printf("Ctrl-Break event\n\n"); 81 | return FALSE; 82 | 83 | case CTRL_LOGOFF_EVENT: 84 | Beep(1000, 200); 85 | printf("Ctrl-Logoff event\n\n"); 86 | return FALSE; 87 | 88 | case CTRL_SHUTDOWN_EVENT: 89 | Beep(750, 500); 90 | printf("Ctrl-Shutdown event\n\n"); 91 | return FALSE; 92 | */ 93 | default: 94 | return FALSE; 95 | } 96 | } 97 | #else 98 | static void sighandler(int signum) 99 | { 100 | printf("Shutdown \n\n"); 101 | //devices::instance().Stop(); 102 | exit(0); 103 | } 104 | #endif 105 | 106 | 107 | int main(int argc, char* argv[]) 108 | { 109 | //test 110 | float a = sqrt(2.0f); 111 | 112 | //test end 113 | rsp_cmdLineArgs* pargs = 0; 114 | eErrors retCode = E_OK; 115 | string sError; 116 | #ifdef _WIN32 117 | WSADATA wsd; 118 | int result = WSAStartup(MAKEWORD(2, 2), &wsd); 119 | if (result != 0) 120 | { 121 | retCode = E_WIN_WSA_STARTUP; 122 | sError = returnErrorStrings[retCode] + to_string(result); 123 | goto exit; 124 | } 125 | if (SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE) == FALSE) 126 | cout << "Error setting ctrl-c handler." << endl; 127 | #else 128 | struct sigaction sigact, sigign; 129 | sigact.sa_handler = sighandler; 130 | sigemptyset(&sigact.sa_mask); 131 | sigact.sa_flags = 0; 132 | sigign.sa_handler = SIG_IGN; 133 | sigaction(SIGINT, &sigact, NULL); 134 | sigaction(SIGTERM, &sigact, NULL); 135 | sigaction(SIGQUIT, &sigact, NULL); 136 | sigaction(SIGPIPE, &sigign, NULL); 137 | #endif 138 | 139 | std::cout << "\nRSP_tcp V" + Version << std::endl; 140 | std::cout << "Copyright (c) Clem Schmidt, qirx.softsyst.com. All rights reserved" << endl; 141 | std::cout << endl; 142 | 143 | pargs = new rsp_cmdLineArgs(argc, argv); 144 | if (pargs->parse() != 0) 145 | { 146 | pargs->displayUsage(); 147 | retCode = E_PARAMETER; 148 | sError = returnErrorStrings[retCode]; 149 | goto exit; 150 | } 151 | std::cout << "IP Address = " + pargs->Address.sIPAddress << endl; 152 | std::cout << "Port Number = " + to_string(pargs->Port) << endl; 153 | std::cout << "Sampling Rate = " + to_string(pargs->SamplingRate) << endl; 154 | std::cout << "Frequency = " + to_string(pargs->Frequency) << endl; 155 | std::cout << "Gain = " + to_string(pargs->Gain) << endl; 156 | std::cout << "BitWidth = " + to_string(pargs->BitWidth) << endl; 157 | std::cout << "Device Index = " + to_string(pargs->requestedDeviceIndex) << endl; 158 | std::cout << "Antenna = " + to_string(pargs->Antenna) << endl; 159 | std::cout << "Verbose = " + to_string(pargs->verbose) << endl; 160 | std::cout << "AM Port = " + to_string(pargs->amPort) << endl; 161 | 162 | cout << "\nStarting sdrplay...\n"; 163 | 164 | gainConfiguration::createGainConfigTables(); 165 | 166 | if (devices::instance().getDevices()) 167 | { 168 | float apiVersion = 0.0f; 169 | mir_sdr_ErrT err = mir_sdr_ApiVersion(&apiVersion); 170 | cout << "\nmir_sdr_ApiVersion returned with: " << err << endl; 171 | cout << "sdrplay API Version " << apiVersion << endl << endl; 172 | 173 | double epsilon = 0.0001; 174 | 175 | if (apiVersion < 2.13 -epsilon && apiVersion > 2.13 + epsilon) 176 | { 177 | retCode = E_WRONG_API_VERSION; 178 | sError = returnErrorStrings[retCode]; 179 | goto exit; 180 | } 181 | 182 | int numDevices = devices::instance().getNumberOfDevices(); 183 | cout << numDevices << " Device(s) found\n"; 184 | if (pargs->requestedDeviceIndex + 1 > numDevices) 185 | { 186 | retCode = E_DEVICE_INDEX; 187 | sError = returnErrorStrings[retCode] + to_string( pargs->requestedDeviceIndex); 188 | goto exit; 189 | } 190 | 191 | map::iterator it; 192 | for (it = devices::instance().mirDevices.begin(); 193 | it != devices::instance().mirDevices.end(); it++) 194 | { 195 | mir_sdr_device* pd = it->second; 196 | cout << "\tSerial: " << pd->serno << endl; 197 | cout << "\tUSB Id: " << pd->DevNm << endl; 198 | cout << "\tHardware Version: " << (int)pd->hwVer << endl; 199 | cout << "\n"; 200 | } 201 | //err = mir_sdr_DebugEnable(1); 202 | //cout << "mir_sdr_DebugEnable(1) returned with " << err << endl; 203 | devices::instance().Start(pargs); 204 | } 205 | else 206 | { 207 | retCode = E_NO_DEVICE; 208 | sError = returnErrorStrings[retCode]; 209 | goto exit; 210 | } 211 | exit: 212 | if (retCode != 0) 213 | { 214 | delete pargs; 215 | cout << sError << endl; 216 | cout << "Application cannot continue. \n" << endl; 217 | //cout << "Please press any character to exit here..." << endl; 218 | //getchar(); 219 | } 220 | #ifdef _WIN32 221 | WSACleanup(); 222 | #endif 223 | return retCode; 224 | 225 | } -------------------------------------------------------------------------------- /rsp_tcp/rsp_tcp.h: -------------------------------------------------------------------------------- 1 | /** 2 | ** RSP_tcp - TCP/IP I/Q Data Server for the sdrplay RSP2 3 | ** Copyright (C) 2017 Clem Schmidt, softsyst GmbH, http://www.softsyst.com 4 | ** 5 | ** This program is free software; you can redistribute it and/or modify 6 | ** it under the terms of the GNU General Public License as published by 7 | ** the Free Software Foundation; either version 2 of the License, or 8 | ** (at your option) any later version. 9 | ** 10 | ** This program is distributed in the hope that it will be useful, 11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ** GNU General Public License for more details. 14 | ** 15 | ** You should have received a copy of the GNU General Public License 16 | ** along with this program; if not, write to the Free Software 17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | ** 19 | **/ 20 | 21 | #pragma once 22 | #include 23 | 24 | enum eBitWidth { BITS_4= 0, BITS_8 = 1, BITS_16 = 2 }; 25 | enum eErrors 26 | { 27 | E_OK = 0 28 | ,E_PARAMETER = -1 29 | ,E_WRONG_API_VERSION = -2 30 | ,E_NO_DEVICE = -3 31 | ,E_DEVICE_INDEX = -4 32 | ,E_WIN_WSA_STARTUP = -10 33 | }; 34 | 35 | enum eRxType 36 | { 37 | RSP1 = 0, 38 | RSP1A, 39 | RSP2, 40 | RSPduo, 41 | UNKNOWN 42 | //RSP1 = 6, 43 | //RSP1A = 7, 44 | //RSP2 = 8, 45 | //RSPduo = 9 46 | }; 47 | 48 | -------------------------------------------------------------------------------- /rsp_tcp/rsp_tcp.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {09435408-8689-459B-87FF-2EB61FAEB665} 23 | Win32Proj 24 | sdrplay_tcp_cpp 25 | 10.0.17763.0 26 | RSP_tcp 27 | 28 | 29 | 30 | Application 31 | true 32 | v141 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v141 39 | true 40 | Unicode 41 | Static 42 | 43 | 44 | Application 45 | true 46 | v141 47 | Unicode 48 | 49 | 50 | Application 51 | false 52 | v141 53 | true 54 | Unicode 55 | Static 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | true 77 | 78 | 79 | true 80 | RSP2_tcp 81 | 82 | 83 | 84 | false 85 | 86 | 87 | false 88 | RSP2_tcp 89 | 90 | 91 | 92 | 93 | 94 | 95 | Level3 96 | Disabled 97 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 98 | true 99 | D:\fun\signalProc\sdrplay\sdrplay_tcp_cpp\posix\include;%(AdditionalIncludeDirectories) 100 | 101 | 102 | Console 103 | true 104 | mir_sdr_api.lib;pthreadVC2.lib;%(AdditionalDependencies) 105 | D:\fun\signalProc\sdrplay\sdrplay_tcp_cpp\posix\lib\x86;%(AdditionalLibraryDirectories) 106 | 107 | 108 | 109 | 110 | 111 | 112 | Level3 113 | Disabled 114 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 115 | true 116 | .\include_ext;%(AdditionalIncludeDirectories) 117 | 118 | 119 | Console 120 | true 121 | mir_sdr_api.lib;pthreadVC2.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 122 | .\lib64;%(AdditionalLibraryDirectories) 123 | 124 | 125 | xcopy /Y .\lib64\*.dll ..\x64\Debug 126 | 127 | 128 | 129 | 130 | Level3 131 | 132 | 133 | MaxSpeed 134 | true 135 | true 136 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 137 | true 138 | .\include_ext;%(AdditionalIncludeDirectories) 139 | MultiThreaded 140 | 141 | 142 | Console 143 | true 144 | true 145 | true 146 | mir_sdr_api.lib;pthreadVC2.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 147 | .\lib32;%(AdditionalLibraryDirectories) 148 | 149 | 150 | 151 | 152 | Level3 153 | 154 | 155 | MaxSpeed 156 | true 157 | true 158 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 159 | true 160 | .\include_ext;%(AdditionalIncludeDirectories) 161 | MultiThreaded 162 | /std:c++14 %(AdditionalOptions) 163 | 164 | 165 | Console 166 | true 167 | true 168 | true 169 | mir_sdr_api.lib;pthreadVC2.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 170 | .\lib64;%(AdditionalLibraryDirectories) 171 | $(OutDir)$(TargetName)$(TargetExt) 172 | false 173 | 174 | 175 | 176 | 177 | 178 | 179 | xcopy /Y .\lib64\*.dll ..\x64\Release 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | -------------------------------------------------------------------------------- /rsp_tcp/rsp_tcp.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -a 127.0.0.1 -p 1234 -W 2 -v 1 -H 1 5 | WindowsLocalDebugger 6 | 7 | 8 | -a 127.0.0.1 -p 1234 -W 2 -g 27 -v 1 -H 0 9 | WindowsLocalDebugger 10 | 11 | 12 | -a 127.0.0.1 -p 1234 -W 1 13 | WindowsLocalDebugger 14 | 15 | -------------------------------------------------------------------------------- /rsp_tcp/sdrGainTable.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | ** RSP_tcp - TCP/IP I/Q Data Server for the sdrplay RSP2 3 | ** Copyright (C) 2017 Clem Schmidt, softsyst GmbH, http://www.softsyst.com 4 | ** 5 | ** This program is free software; you can redistribute it and/or modify 6 | ** it under the terms of the GNU General Public License as published by 7 | ** the Free Software Foundation; either version 2 of the License, or 8 | ** (at your option) any later version. 9 | ** 10 | ** This program is distributed in the hope that it will be useful, 11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ** GNU General Public License for more details. 14 | ** 15 | ** You should have received a copy of the GNU General Public License 16 | ** along with this program; if not, write to the Free Software 17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | ** 19 | **/ 20 | 21 | #include 22 | #include "IPAddress.h" 23 | #include "rsp_cmdLineArgs.h" 24 | #include "common.h" 25 | #include 26 | #include "sdrGainTable.h" 27 | 28 | // 1st dim: Band, 2nd dim gr value for LNAstate 29 | matrix gainTables[4]; 30 | 31 | void gainConfiguration::createGainConfigTables() 32 | { 33 | //RSP1 34 | 35 | // LNAstates, bands, init value 36 | // RSP1 37 | gainTables[0].setSize(4, 6, 0); 38 | 39 | // RSP1A 40 | gainTables[1].setSize(10, 6, 0); 41 | 42 | // RSP2 43 | gainTables[2].setSize(9, 7, 0); 44 | 45 | //RSPduo 46 | gainTables[3].setSize(10, 7, 0); 47 | 48 | // *********** RSP1 ************** 49 | 50 | //LNAstate 0 51 | for (int k = 0; k < 6; k++) 52 | gainTables[0][0][k] = 0; 53 | 54 | //LNAstate 1 55 | for (int k = 0; k < 4; k++) 56 | gainTables[0][1][k] = 24; 57 | gainTables[0][1][4] = 7; 58 | gainTables[0][1][5] = 5; 59 | 60 | //LNAstate 2 61 | for (int k = 0; k < 6; k++) 62 | gainTables[0][2][k] = 19; 63 | 64 | //LNAstate 3 65 | for (int k = 0; k < 4; k++) 66 | gainTables[0][3][k] = 43; 67 | gainTables[0][3][4] = 26; 68 | gainTables[0][3][5] = 24; 69 | 70 | // *********** RSP1A ************** 71 | //LNAstate 0 72 | for (int k = 0; k < 6; k++) 73 | gainTables[1][0][k] = 0; 74 | 75 | //LNAstate 1 76 | for (int k = 0; k < 6; k++) 77 | gainTables[1][1][k] = 6; 78 | gainTables[1][1][4] = 7; 79 | 80 | //LNAstate 2 81 | for (int k = 0; k < 6; k++) 82 | gainTables[1][2][k] = 12; 83 | gainTables[1][2][4] = 13; 84 | 85 | //LNAstate 3 86 | for (int k = 0; k < 4; k++) 87 | gainTables[1][3][k] = 18; 88 | gainTables[1][3][4] = 19; 89 | gainTables[1][3][5] = 20; 90 | 91 | //LNAstate 4 92 | for (int k = 1; k < 5; k++) 93 | gainTables[1][4][k] = 20; 94 | gainTables[1][4][0] = 37; 95 | gainTables[1][4][5] = 26; 96 | 97 | //LNAstate 5 98 | for (int k = 1; k < 5; k++) 99 | gainTables[1][5][k] = 26; 100 | gainTables[1][5][0] = 42; 101 | gainTables[1][5][4] = 27; 102 | gainTables[1][5][5] = 32; 103 | 104 | //LNAstate 6 105 | for (int k = 1; k < 5; k++) 106 | gainTables[1][6][k] = 32; 107 | gainTables[1][6][0] = 61; 108 | gainTables[1][6][4] = 33; 109 | gainTables[1][6][5] = 38; 110 | 111 | //LNAstate 7 112 | for (int k = 1; k < 5; k++) 113 | gainTables[1][7][k] = 38; 114 | gainTables[1][7][0] = 1000; 115 | gainTables[1][7][4] = 39; 116 | gainTables[1][7][5] = 43; 117 | 118 | //LNAstate 8 119 | for (int k = 1; k < 5; k++) 120 | gainTables[1][8][k] = 57; 121 | gainTables[1][8][0] = 1000; 122 | gainTables[1][8][4] = 45; 123 | gainTables[1][8][5] = 62; 124 | 125 | //LNAstate 9 126 | for (int k = 1; k < 5; k++) 127 | gainTables[1][9][k] = 62; 128 | gainTables[1][9][0] = 1000; 129 | gainTables[1][9][4] = 64; 130 | gainTables[1][9][5] = 1000; 131 | 132 | 133 | // *********** RSP2 ************** 134 | //LNAstate 0 135 | for (int k = 0; k < 7; k++) 136 | gainTables[2][0][k] = 0; 137 | 138 | //LNAstate 1 139 | for (int k = 0; k < 4; k++) 140 | gainTables[2][1][k] = 10; 141 | gainTables[2][1][4] = 7; 142 | gainTables[2][1][5] = 5; 143 | gainTables[2][1][6] = 6; 144 | 145 | //LNAstate 2 146 | for (int k = 0; k < 4; k++) 147 | gainTables[2][2][k] = 15; 148 | gainTables[2][2][4] = 10; 149 | gainTables[2][2][5] = 21; 150 | gainTables[2][2][6] = 12; 151 | 152 | //LNAstate 3 153 | for (int k = 0; k < 4; k++) 154 | gainTables[2][3][k] = 21; 155 | gainTables[2][3][4] = 17; 156 | gainTables[2][3][5] = 15; 157 | gainTables[2][3][6] = 18; 158 | 159 | //LNAstate 4 160 | for (int k = 0; k < 4; k++) 161 | gainTables[2][4][k] = 24; 162 | gainTables[2][4][4] = 22; 163 | gainTables[2][4][5] = 15; 164 | gainTables[2][4][6] = 37; 165 | 166 | //LNAstate 5 167 | for (int k = 0; k < 4; k++) 168 | gainTables[2][5][k] = 34; 169 | gainTables[2][5][4] = 41; 170 | gainTables[2][5][5] = 34; 171 | gainTables[2][5][6] = 1000; 172 | 173 | //LNAstate 6 174 | for (int k = 0; k < 4; k++) 175 | gainTables[2][6][k] = 39; 176 | gainTables[2][6][4] = 1000; 177 | gainTables[2][6][5] = 1000; 178 | gainTables[2][6][6] = 1000; 179 | 180 | //LNAstate 7 181 | for (int k = 0; k < 4; k++) 182 | gainTables[2][7][k] = 45; 183 | gainTables[2][7][4] = 1000; 184 | gainTables[2][7][5] = 1000; 185 | gainTables[2][7][6] = 1000; 186 | 187 | //LNAstate 8 188 | for (int k = 0; k < 4; k++) 189 | gainTables[2][8][k] = 64; 190 | gainTables[2][8][4] = 1000; 191 | gainTables[2][8][5] = 1000; 192 | gainTables[2][8][6] = 1000; 193 | 194 | // *********** RSPduo ************** 195 | //LNAstate 0 196 | for (int k = 0; k < 7; k++) 197 | gainTables[3][0][k] = 0; 198 | 199 | //LNAstate 1 200 | for (int k = 0; k < 7; k++) 201 | gainTables[3][1][k] = 6; 202 | gainTables[3][1][4] = 7; 203 | 204 | //LNAstate 2 205 | for (int k = 0; k < 7; k++) 206 | gainTables[3][2][k] = 12; 207 | gainTables[3][2][4] = 13; 208 | 209 | //LNAstate 3 210 | for (int k = 0; k < 7; k++) 211 | gainTables[3][3][k] = 18; 212 | gainTables[3][3][4] = 19; 213 | gainTables[3][3][5] = 20; 214 | 215 | //LNAstate 4 216 | for (int k = 0; k < 7; k++) 217 | gainTables[3][4][k] = 20; 218 | gainTables[3][4][0] = 37; 219 | gainTables[3][4][5] = 26; 220 | gainTables[3][4][6] = 37; 221 | 222 | //LNAstate 5 223 | for (int k = 0; k < 6; k++) 224 | gainTables[3][5][k] = 26; 225 | gainTables[3][5][0] = 42; 226 | gainTables[3][5][4] = 27; 227 | gainTables[3][5][5] = 32; 228 | gainTables[3][5][6] = 1000; 229 | 230 | //LNAstate 6 231 | for (int k = 0; k < 4; k++) 232 | gainTables[3][6][k] = 32; 233 | gainTables[3][6][0] = 61; 234 | gainTables[3][6][4] = 33; 235 | gainTables[3][6][5] = 38; 236 | gainTables[3][6][6] = 1000; 237 | 238 | //LNAstate 7 239 | for (int k = 1; k < 4; k++) 240 | gainTables[3][7][k] = 38; 241 | gainTables[3][7][4] = 39; 242 | gainTables[3][7][5] = 43; 243 | gainTables[3][7][0] = 1000; 244 | gainTables[3][7][6] = 1000; 245 | 246 | //LNAstate 8 247 | for (int k = 1; k < 4; k++) 248 | gainTables[3][8][k] = 57; 249 | gainTables[3][8][4] = 45; 250 | gainTables[3][8][5] = 62; 251 | gainTables[3][8][0] = 1000; 252 | gainTables[3][8][6] = 1000; 253 | 254 | //LNAstate 9 255 | for (int k = 1; k < 4; k++) 256 | gainTables[3][9][k] = 62; 257 | gainTables[3][9][4] = 64; 258 | gainTables[3][9][0] = 1000; 259 | gainTables[3][9][5] = 1000; 260 | gainTables[3][9][6] = 1000; 261 | 262 | } 263 | 264 | gainConfiguration::gainConfiguration(mir_sdr_BandT band) : band(band) 265 | { 266 | myBand = bandId[band]; 267 | } 268 | 269 | /* 270 | bool gainConfiguration::calculateGrValues(int flatValue, int rxtype, int& LNAstate, int& gr) 271 | { 272 | if (flatValue < 0 || flatValue > GAIN_STEPS) // 100 GAIN_STEPS 273 | return false; 274 | 275 | // convert gain to gainReduction 276 | int flatGr = GAIN_STEPS - flatValue; 277 | 278 | // map the 100 steps to a range between 0 and 62, according to the GR Tables 279 | float minLNAgr = 0.0f; 280 | float maxLNAgr = 62.0f; 281 | float f_flatGr2 = (float)flatGr * (maxLNAgr - minLNAgr) /(float)GAIN_STEPS + minLNAgr; 282 | int flatGr2 = (int)(f_flatGr2 ); 283 | 284 | 285 | try 286 | { 287 | matrix gainTable = gainTables[rxtype]; 288 | 289 | //search for a reasonable combination of gr and LNAstate 290 | int lnaStates = LNAstates[rxtype][myBand]; 291 | 292 | for (int i = lnaStates-2; i >= 0; i--) 293 | { 294 | int val = gainTable[i][myBand]; 295 | int val2 = gainTable[i+1][myBand]; 296 | int delta = val2 - val -2; 297 | if ((flatGr2 < val + delta) && (flatGr2 > val - delta)) 298 | { 299 | LNAstate = i; 300 | gr = flatGr2; 301 | return true; 302 | } 303 | } 304 | //// search the lnastates table from 0 until the first value in range is found 305 | //// Take it as the gr corresponding to the lnastate 306 | //for (int i = 0; i < lnaStates; i++) 307 | //{ 308 | // int val = gainTable[i][myBand]; 309 | // gr = flatGr - val; 310 | // if (gr >= 20 && gr < 60) 311 | // { 312 | // LNAstate = i; 313 | // return true; 314 | // } 315 | //} 316 | return false; 317 | } 318 | catch (const std::exception&) 319 | { 320 | 321 | } 322 | return false; 323 | } 324 | */ 325 | 326 | bool gainConfiguration::calculateGrValues(int flatValue, int rxtype, int& LNAstate, int& gr) 327 | { 328 | if (flatValue < 0 || flatValue > GAIN_STEPS) 329 | return false; 330 | 331 | // convert gain to gainReduction 332 | int flatGr = GAIN_STEPS - flatValue; 333 | 334 | // min reasonable gr 335 | if (flatGr < 20) 336 | { 337 | flatGr = 20; 338 | LNAstate = 0; 339 | gr = flatGr; 340 | return true; 341 | } 342 | 343 | try 344 | { 345 | matrix gainTable = gainTables[rxtype]; 346 | 347 | //search for a reasonable combination of gr and LNAstate 348 | int lnaStates = LNAstates[rxtype][myBand]; 349 | 350 | //// collect all fitting lna states 351 | //vector statesInRange; 352 | //for (int i = lnaStates-1; i >= 0; i--) 353 | //{ 354 | // int val = gainTable[i][myBand]; 355 | // gr = flatGr - val; 356 | // if (gr >= 20 && gr < 60) 357 | // { 358 | // statesInRange.push_back(i); 359 | // } 360 | //} 361 | //// look for the minimal lna state 362 | //int minLna = 100; 363 | //int maxLna = -1; 364 | //for (int i = 0; i < statesInRange.size(); i++) 365 | //{ 366 | // if (statesInRange[i] < minLna) 367 | // minLna = statesInRange[i]; 368 | // if (statesInRange[i] > maxLna) 369 | // maxLna = statesInRange[i]; 370 | //} 371 | //LNAstate = (minLna+maxLna) / 2; 372 | //int val = gainTable[minLna][myBand]; 373 | //gr = flatGr - val; 374 | //if (gr < 20) 375 | //{ 376 | // while (gr < 20) 377 | // gr++; 378 | //} 379 | //else if (gr > 60) 380 | //{ 381 | // while (gr > 60) 382 | // gr--; 383 | //} 384 | //else 385 | // return true; 386 | 387 | 388 | //for (int i = lnaStates-1; i >= 0; i--) 389 | //{ 390 | // int val = gainTable[i][myBand]; 391 | // gr = flatGr - val; 392 | // if (gr >= 20 && gr < 60) 393 | // { 394 | // LNAstate = i; 395 | // return true; 396 | // } 397 | //} 398 | //search the lnastates table from 0 until the first value in range is found 399 | //Take it as the gr corresponding to the lnastate 400 | for (int i = 0; i < lnaStates; i++) 401 | { 402 | int val = gainTable[i][myBand]; 403 | gr = flatGr - val; 404 | if (gr >= 20 && gr < 60) 405 | { 406 | LNAstate = i; 407 | return true; 408 | } 409 | } 410 | return false; 411 | 412 | } 413 | catch (const std::exception&) 414 | { 415 | 416 | } 417 | return false; 418 | } 419 | -------------------------------------------------------------------------------- /rsp_tcp/sdrGainTable.h: -------------------------------------------------------------------------------- 1 | /** 2 | ** RSP_tcp - TCP/IP I/Q Data Server for the sdrplay RSP2 3 | ** Copyright (C) 2017 Clem Schmidt, softsyst GmbH, http://www.softsyst.com 4 | ** 5 | ** This program is free software; you can redistribute it and/or modify 6 | ** it under the terms of the GNU General Public License as published by 7 | ** the Free Software Foundation; either version 2 of the License, or 8 | ** (at your option) any later version. 9 | ** 10 | ** This program is distributed in the hope that it will be useful, 11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ** GNU General Public License for more details. 14 | ** 15 | ** You should have received a copy of the GNU General Public License 16 | ** along with this program; if not, write to the Free Software 17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | ** 19 | **/ 20 | 21 | #pragma once 22 | #include "rsp_tcp.h" 23 | #include "mir_sdr.h" 24 | #include "syTwoDimArray.h" 25 | 26 | struct gainConfiguration 27 | { 28 | static void createGainConfigTables(); 29 | 30 | const int internalBands = 7; 31 | // get the band id of the matrix tables 32 | // the AM(HiZ Port) is not covered by mir_sdr_BandT 33 | const int bandId[(int)mir_sdr_BAND_L + 2] = { 0,0,0, 1,2,3,4,5,6 }; 34 | int LNAstates[4][7] = //number of LNAstates depending on rxType and band 35 | { 36 | {4,4,4,4,4,4,0}, 37 | {7,10,10,10,10, 9, 0}, 38 | {9,9,9,9,6,6,5}, 39 | {7,10,10,10,10,9,5} 40 | }; 41 | 42 | //Assumed gain steps for the RSP2 43 | //This is "quick and dirty" due to the overall complexity of the RSPs gain settings 44 | static const int GAIN_STEPS = 100; 45 | 46 | mir_sdr_BandT band; 47 | 48 | // the internally used band, converted from band 49 | int myBand; 50 | 51 | gainConfiguration(mir_sdr_BandT band); 52 | 53 | bool calculateGrValues(int flatValue, int rxtype, int& LNAstate, int& gr); 54 | }; 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /rsp_tcp/syTwoDimArray.h: -------------------------------------------------------------------------------- 1 | //matrix------------------------------------------------------------------------ 2 | // 3 | // Subsystem : None, general purpose class 4 | // Classes : matrix 5 | // Purpose : Twodimensional dynamical array 6 | // 7 | // Author : Clemens Schmidt, adapted from "STL konzentriert" 8 | //------------------------------------------------------------------------------ 9 | // Ver. |Release| Auth| Change | Remarks 10 | //------------------------------------------------------------------------------ 11 | // 1.0 |19Nov00| CS | | 12 | // 1.1 |06Jun02| CS | private inheritance,operator[] | 13 | // 1.2 |06Jun02| CS | typename | 14 | // 1.2 |28Oct05| CS | setSize | 15 | //------------------------------------------------------------------------------ 16 | // (c)softsyst GmbH, Tel: +49-7551-932 855, www.softsyst.com 17 | //------------------------------------------------------------------------------ 18 | // 19 | ////////////////////////////////////////////////////////////////////// 20 | // matrix 21 | #ifndef matrix_t 22 | #define matrix_t 23 | #pragma warning (disable:4786) 24 | #include 25 | #include 26 | using namespace std; 27 | // matrix als Vektor von Vektoren 28 | 29 | template 30 | class matrix : private vector > 31 | { 32 | typedef typename vector::size_type size_type ; 33 | 34 | public: 35 | matrix(size_type x = 0, size_type y = 0) 36 | : vector >(x,vector(y)){} 37 | ///////////////////////// 38 | size_type rows() const {return size(); } 39 | size_type columns() const 40 | { 41 | if (size() > 0) 42 | return at(0).size(); 43 | else 44 | return 0; 45 | } 46 | ///////////////////////// 47 | vector& operator[] (const size_type& ix){return at(ix);} 48 | ///////////////////////// 49 | void setSize (const size_type rows, const size_type cols, const T& value) 50 | { 51 | clear_all(); //this is mandatory in case only cols change!!!! Otherwise no action is taken 52 | //because the resize(rows, colvect) is a NOP if rows did not change. 53 | vector colvect; 54 | colvect.resize(cols, value); 55 | resize (rows, colvect); 56 | } 57 | 58 | ///////////////////////// 59 | void clear_all() 60 | { 61 | for (size_type i = 0; i < size(); i++) 62 | at(i).clear(); 63 | clear(); 64 | } 65 | 66 | 67 | ///////////////////////// 68 | void init(const T& Wert) 69 | { 70 | for (size_type i = 0; i < rows(); i++) 71 | for (size_type j = 0; j < columns() ; j++) 72 | at(i)[j] = Wert; 73 | //operator[](i)[j] = Wert; 74 | //(operator[](i)).operator[](j) = Wert; 75 | } 76 | ///////////////////////// 77 | void insertRow(const int row, const int columns, const T& value) 78 | { 79 | vector colvect; 80 | colvect.resize(columns, value); 81 | iterator it = begin(); 82 | advance(it, row); 83 | insert(it, colvect); 84 | } 85 | ///////////////////////// 86 | void removeRow(const int row) 87 | { 88 | if (row < 0 || row > rows()) 89 | return; 90 | iterator it = begin(); 91 | advance(it, row); 92 | erase (it); 93 | } 94 | ////////////////////////////////////////////////////////////////////// 95 | //order < 0 : row1 precedes row2 96 | //order > 0 : row2 precedes row1 97 | //order == 0: no change 98 | void reorderRows(int row1, int row2, int order) 99 | { 100 | if (row1 < 0 || row2 < 0 || row1 >= rows() || row2 >= rows()) 101 | return; 102 | if (order == 0) 103 | return; 104 | 105 | vector colvect; 106 | int first, second; 107 | if (order < 0) 108 | { 109 | first = row1; 110 | second = row2; 111 | } 112 | else 113 | { 114 | first = row2; 115 | second = row1; 116 | } 117 | 118 | //test 119 | T t; 120 | for (int i=0; i < rows(); i++) 121 | t = at(i)[3]; 122 | 123 | iterator it, it2; 124 | it = begin(); 125 | advance(it, first); 126 | colvect = at(first); //this colvect has to be inserted before "second" 127 | 128 | if (second > first) 129 | second--; 130 | erase (it); 131 | it2 = begin(); 132 | advance (it2, second); 133 | insert(it2, colvect); 134 | 135 | for ( i=0; i < rows(); i++) 136 | t = at(i)[3]; 137 | 138 | } 139 | }; 140 | 141 | template 142 | ostream& operator<<(ostream& s, const matrix& m ) 143 | { 144 | typedef vector::size_type size_type; 145 | for (size_type i = 0; i < m.rows(); i++) 146 | { s << endl << i <<" : "; 147 | for (size_type j = 0; j < m.columns(); j++) 148 | s << m[i][j] <<" "; 149 | } 150 | s <