summaryrefslogtreecommitdiffstats
path: root/src/host/layer23/src/common/sysinfo.c
diff options
context:
space:
mode:
authorAndreas.Eversberg <jolly@eversberg.eu>2011-03-16 08:52:01 +0000
committerSylvain Munaut <tnt@246tNt.com>2011-05-29 19:51:54 +0200
commit58ac7e0e98c448dcece8e7dfa53f484c982e96cf (patch)
tree9e81e18348a4b3cf76dc3b204a5493f1f9e6cca1 /src/host/layer23/src/common/sysinfo.c
parent16ec2358a014f290be47e87e3489f98769681979 (diff)
[layer23] Adding Quadband support and GSM 4x0 support
This makes it possible to use GSM 850 and PCS 1900 bands, as used in the US. The support relies on the phone hardware. Each band (900, DCS, 850, PCS, 480 and 450) can be enabled and disabled individually for each setting.
Diffstat (limited to 'src/host/layer23/src/common/sysinfo.c')
-rw-r--r--src/host/layer23/src/common/sysinfo.c85
1 files changed, 72 insertions, 13 deletions
diff --git a/src/host/layer23/src/common/sysinfo.c b/src/host/layer23/src/common/sysinfo.c
index 5827d756..92a0516d 100644
--- a/src/host/layer23/src/common/sysinfo.c
+++ b/src/host/layer23/src/common/sysinfo.c
@@ -37,14 +37,47 @@
* dumping
*/
+// FIXME: move to libosmocore
+char *gsm_print_arfcn(uint16_t arfcn)
+{
+ static char text[10];
+
+ sprintf(text, "%d", arfcn & 1023);
+ if ((arfcn & ARFCN_PCS))
+ strcat(text, "(PCS)");
+ else if (arfcn >= 512 && arfcn <= 885)
+ strcat(text, "(DCS)");
+
+ return text;
+}
+
+/* check if the cell 'talks' about DCS (0) or PCS (1) */
+uint8_t gsm_refer_pcs(uint16_t arfcn, struct gsm48_sysinfo *s)
+{
+ /* If ARFCN is PCS band, the cell refers to PCS */
+ if ((arfcn & ARFCN_PCS))
+ return 1;
+
+ /* If no SI1 is available, we assume DCS. Be sure to call this
+ * function only if SI 1 is available. */
+ if (!s->si1)
+ return 0;
+
+ /* If band indicator indicates PCS band, the cell refers to PCSThe */
+ return s->band_ind;
+}
+
int gsm48_sysinfo_dump(struct gsm48_sysinfo *s, uint16_t arfcn,
- void (*print)(void *, const char *, ...), void *priv)
+ void (*print)(void *, const char *, ...), void *priv, uint8_t *freq_map)
{
char buffer[81];
- int i, j, k;
+ int i, j, k, index;
+ int refer_pcs = gsm_refer_pcs(arfcn, s);
/* available sysinfos */
- print(priv, "ARFCN = %d\n", arfcn);
+ print(priv, "ARFCN = %s channels 512+ refer to %s\n",
+ gsm_print_arfcn(arfcn),
+ (refer_pcs) ? "PCS (1900)" : "DCS (1800)");
print(priv, "Available SYSTEM INFORMATIONS =");
if (s->si1)
print(priv, " 1");
@@ -142,13 +175,11 @@ int gsm48_sysinfo_dump(struct gsm48_sysinfo *s, uint16_t arfcn,
/* frequency map */
for (i = 0; i < 1024; i += 64) {
- if (i < 10)
- sprintf(buffer, " %d ", i);
- else if (i < 100)
- sprintf(buffer, " %d ", i);
- else
- sprintf(buffer, " %d ", i);
+ sprintf(buffer, " %3d ", i);
for (j = 0; j < 64; j++) {
+ index = i+j;
+ if (refer_pcs && index >= 512 && index <= 885)
+ index = index-512+1024;
if ((s->freq[i+j].mask & FREQ_TYPE_SERV))
buffer[j + 5] = 'S';
else if ((s->freq[i+j].mask & FREQ_TYPE_NCELL)
@@ -158,9 +189,14 @@ int gsm48_sysinfo_dump(struct gsm48_sysinfo *s, uint16_t arfcn,
buffer[j + 5] = 'n';
else if ((s->freq[i+j].mask & FREQ_TYPE_REP))
buffer[j + 5] = 'r';
- else
+ else if (!freq_map || (freq_map[index >> 3]
+ & (1 << (index & 7))))
buffer[j + 5] = '.';
+ else
+ buffer[j + 5] = ' ';
}
+ for (; j < 64; j++)
+ buffer[j + 5] = ' ';
sprintf(buffer + 69, " %d", i + 63);
print(priv, "%s\n", buffer);
}
@@ -461,6 +497,22 @@ static int gsm48_decode_rach_ctl_neigh(struct gsm48_sysinfo *s,
static int gsm48_decode_si1_rest(struct gsm48_sysinfo *s, uint8_t *si,
uint8_t len)
{
+ struct bitvec bv;
+
+ memset(&bv, 0, sizeof(bv));
+ bv.data_len = len;
+ bv.data = si;
+
+ /* Optional Selection Parameters */
+ if (bitvec_get_bit_high(&bv) == H) {
+ s->nch = 1;
+ s->nch_position = bitvec_get_uint(&bv, 5);
+ } else
+ s->nch = 0;
+ if (bitvec_get_bit_high(&bv) == H)
+ s->band_ind = 1;
+ else
+ s->band_ind = 0;
return 0;
}
@@ -481,23 +533,30 @@ static int gsm48_decode_si3_rest(struct gsm48_sysinfo *s, uint8_t *si,
s->sp_cro = bitvec_get_uint(&bv, 6);
s->sp_to = bitvec_get_uint(&bv, 3);
s->sp_pt = bitvec_get_uint(&bv, 5);
- }
+ } else
+ s->sp = 0;
/* Optional Power Offset */
if (bitvec_get_bit_high(&bv) == H) {
s->po = 1;
s->po_value = bitvec_get_uint(&bv, 3);
- }
+ } else
+ s->po = 0;
/* System Onformation 2ter Indicator */
if (bitvec_get_bit_high(&bv) == H)
s->si2ter_ind = 1;
+ else
+ s->si2ter_ind = 0;
/* Early Classark Sending Control */
if (bitvec_get_bit_high(&bv) == H)
s->ecsm = 1;
+ else
+ s->ecsm = 0;
/* Scheduling if and where */
if (bitvec_get_bit_high(&bv) == H) {
s->sched = 1;
s->sched_where = bitvec_get_uint(&bv, 3);
- }
+ } else
+ s->sched = 0;
/* GPRS Indicator */
s->gi_ra_colour = bitvec_get_uint(&bv, 3);
s->gi_si13_pos = bitvec_get_uint(&bv, 1);