kalibrate-rtl/src/arfcn_freq.cc
Steve Markgraf ed733cc952 fix scanning of E-GSM-900
Signed-off-by: Steve Markgraf <steve@steve-m.de>
2012-10-09 21:14:51 +02:00

322 lines
6.3 KiB
C++

/*
* Copyright (c) 2010, Joshua Lackey
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "arfcn_freq.h"
const char *bi_to_str(int bi) {
switch(bi) {
case GSM_850:
return "GSM-850";
case GSM_R_900:
return "GSM-R-900";
case GSM_900:
return "GSM-900";
case GSM_E_900:
return "E-GSM-900";
case DCS_1800:
return "DCS-1800";
case PCS_1900:
return "PCS-1900";
default:
return "unknown band indicator";
}
}
int str_to_bi(char *s) {
if(!strcmp(s, "GSM850") || !strcmp(s, "GSM-850") || !strcmp(s, "850"))
return GSM_850;
if(!strcmp(s, "GSM-R") || !strcmp(s, "R-GSM"))
return GSM_R_900;
if(!strcmp(s, "GSM900") || !strcmp(s, "GSM-900") || !strcmp(s, "900"))
return GSM_900;
if(!strcmp(s, "EGSM") || !strcmp(s, "E-GSM") || !strcmp(s, "EGSM900") ||
!strcmp(s, "E-GSM900") || !strcmp(s, "E-GSM-900"))
return GSM_E_900;
if(!strcmp(s, "DCS") || !strcmp(s, "DCS1800") ||
!strcmp(s, "DCS-1800") || !strcmp(s, "1800"))
return DCS_1800;
if(!strcmp(s, "PCS") || !strcmp(s, "PCS1900") ||
!strcmp(s, "PCS-1900") || !strcmp(s, "1900"))
return PCS_1900;
return -1;
}
double arfcn_to_freq(int n, int *bi) {
if((128 <= n) && (n <= 251)) {
if(bi)
*bi = GSM_850;
return 824.2e6 + 0.2e6 * (n - 128) + 45.0e6;
}
if((1 <= n) && (n <= 124)) {
if(bi && (*bi != GSM_E_900))
*bi = GSM_900;
return 890.0e6 + 0.2e6 * n + 45.0e6;
}
if(n == 0) {
if(bi)
*bi = GSM_E_900;
return 935e6;
}
if((955 <= n) && (n <= 1023)) {
if(bi) {
if (975 <= n)
*bi = GSM_E_900;
else
*bi = GSM_R_900;
}
return 890.0e6 + 0.2e6 * (n - 1024) + 45.0e6;
}
if((512 <= n) && (n <= 810)) {
if(!bi) {
fprintf(stderr, "error: ambiguous arfcn: %d\n", n);
return -1.0;
}
if(*bi == DCS_1800)
return 1710.2e6 + 0.2e6 * (n - 512) + 95.0e6;
if(*bi == PCS_1900)
return 1850.2e6 + 0.2e6 * (n - 512) + 80.0e6;
fprintf(stderr, "error: bad (arfcn, band indicator) pair: "
"(%d, %s)\n", n, bi_to_str(*bi));
return -1.0;
}
if((811 <= n) && (n <= 885)) {
if(bi)
*bi = DCS_1800;
return 1710.2e6 + 0.2e6 * (n - 512) + 95.0e6;
}
fprintf(stderr, "error: bad arfcn: %d\n", n);
return -1.0;
}
int freq_to_arfcn(double freq, int *bi) {
if((869.2e6 <= freq) && (freq <= 893.8e6)) {
if(bi)
*bi = GSM_850;
return (int)((freq - 869.2e6) / 0.2e6) + 128;
}
if((921.2e6 <= freq) && (freq <= 925.0e6)) {
if(bi)
*bi = GSM_R_900;
return (int)((freq - 935e6) / 0.2e6) + 1024;
}
if((935.2e6 <= freq) && (freq <= 959.8e6)) {
if(bi)
*bi = GSM_900;
return (int)((freq - 935e6) / 0.2e6);
}
if(935.0e6 == freq) {
if(bi)
*bi = GSM_E_900;
return 0;
}
if((925.2e6 <= freq) && (freq <= 934.8e6)) {
if(bi)
*bi = GSM_E_900;
return (int)((freq - 935e6) / 0.2e6) + 1024;
}
if((1805.2e6 <= freq) && (freq <= 1879.8e6)) {
if(bi)
*bi = DCS_1800;
return (int)((freq - 1805.2e6) / 0.2e6) + 512;
}
if((1930.2e6 <= freq) && (freq <= 1989.8e6)) {
if(bi)
*bi = PCS_1900;
return (int)((freq - 1930.2e6) / 0.2e6) + 512;
}
fprintf(stderr, "error: bad frequency: %lf\n", freq);
return -1;
}
int first_chan(int bi) {
switch(bi) {
case GSM_850:
return 128;
case GSM_R_900:
return 955;
case GSM_900:
return 1;
case GSM_E_900:
return 0;
case DCS_1800:
return 512;
case PCS_1900:
return 512;
default:
return -1;
}
return -1;
}
int next_chan_loop(int chan, int bi) {
switch(bi) {
case GSM_850:
if((128 <= chan) && (chan < 251))
return chan + 1;
if(chan == 251)
return 128;
return -1;
case GSM_R_900:
if((955 <= chan) && (chan < 974))
return chan + 1;
if(chan == 974)
return 955;
return -1;
case GSM_900:
if((1 <= chan) && (chan < 124))
return chan + 1;
if(chan == 124)
return 1;
return -1;
case GSM_E_900:
if((0 <= chan) && (chan < 124))
return chan + 1;
if(chan == 124)
return 975;
if((975 <= chan) && (chan < 1023))
return chan + 1;
if(chan == 1023)
return 0;
return -1;
case DCS_1800:
if((512 <= chan) && (chan < 885))
return chan + 1;
if(chan == 885)
return 512;
return -1;
case PCS_1900:
if((512 <= chan) && (chan < 810))
return chan + 1;
if(chan == 810)
return 512;
return -1;
default:
return -1;
}
return -1;
}
int next_chan(int chan, int bi) {
switch(bi) {
case GSM_850:
if((128 <= chan) && (chan < 251))
return chan + 1;
return -1;
case GSM_R_900:
if((955 <= chan) && (chan < 974))
return chan + 1;
return -1;
case GSM_900:
if((1 <= chan) && (chan < 124))
return chan + 1;
return -1;
case GSM_E_900:
if((0 <= chan) && (chan < 124))
return chan + 1;
if(chan == 124)
return 975;
if((975 <= chan) && (chan < 1023))
return chan + 1;
return -1;
case DCS_1800:
if((512 <= chan) && (chan < 885))
return chan + 1;
return -1;
case PCS_1900:
if((512 <= chan) && (chan < 810))
return chan + 1;
return -1;
default:
return -1;
}
return -1;
}