summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2011-01-23 14:16:54 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2011-01-23 14:29:44 +0100
commitd1790b99408343a4d60afa6482ec4f7fa050b764 (patch)
treee0b08b9da94f3d42644bd16aa38e2b7f3f7c6d72
parent9d90193dee78bbfedbbfe0bfbf3234514ee0036c (diff)
ccch: Decode the paging1 type paging requests
Th size checks are a bit messy and I have not seen an optional MI yet. So this code path is not tested at all.
-rw-r--r--src/host/layer23/src/misc/app_ccch_scan.c113
1 files changed, 112 insertions, 1 deletions
diff --git a/src/host/layer23/src/misc/app_ccch_scan.c b/src/host/layer23/src/misc/app_ccch_scan.c
index 8e5528f0..1f1a3e8d 100644
--- a/src/host/layer23/src/misc/app_ccch_scan.c
+++ b/src/host/layer23/src/misc/app_ccch_scan.c
@@ -28,6 +28,7 @@
#include <osmocore/rsl.h>
#include <osmocore/tlv.h>
#include <osmocore/gsm48_ie.h>
+#include <osmocore/gsm48.h>
#include <osmocore/signal.h>
#include <osmocore/protocol/gsm_04_08.h>
@@ -226,6 +227,112 @@ static int gsm48_rx_imm_ass(struct msgb *msg, struct osmocom_ms *ms)
return 0;
}
+static const char *pag_print_mode(int mode)
+{
+ switch (mode) {
+ case 0:
+ return "Normal paging";
+ case 1:
+ return "Extended paging";
+ case 2:
+ return "Paging reorganization";
+ case 3:
+ return "Same as before";
+ default:
+ return "invalid";
+ }
+}
+
+static char *chan_need(int need)
+{
+ switch (need) {
+ case 0:
+ return "any";
+ case 1:
+ return "sdch";
+ case 2:
+ return "tch/f";
+ case 3:
+ return "tch/h";
+ default:
+ return "invalid";
+ }
+}
+
+static char *mi_type_to_string(int type)
+{
+ switch (type) {
+ case GSM_MI_TYPE_NONE:
+ return "none";
+ case GSM_MI_TYPE_IMSI:
+ return "imsi";
+ case GSM_MI_TYPE_IMEI:
+ return "imei";
+ case GSM_MI_TYPE_IMEISV:
+ return "imeisv";
+ case GSM_MI_TYPE_TMSI:
+ return "tmsi";
+ default:
+ return "invalid";
+ }
+}
+
+/**
+ * This can contain two MIs. The size checking is a bit of a mess.
+ */
+static int gsm48_rx_paging_p1(struct msgb *msg, struct osmocom_ms *ms)
+{
+ struct gsm48_paging1 *pag;
+ int len1, len2, mi_type, tag;
+ char mi_string[GSM48_MI_SIZE];
+
+ /* is there enough room for the header + LV? */
+ if (msgb_l3len(msg) < sizeof(*pag) + 2) {
+ LOGP(DRR, LOGL_ERROR, "PagingRequest is too short.\n");
+ return -1;
+ }
+
+ pag = msgb_l3(msg);
+ len1 = pag->data[0];
+ mi_type = pag->data[1] & GSM_MI_TYPE_MASK;
+
+ if (msgb_l3len(msg) < sizeof(*pag) + 2 + len1) {
+ LOGP(DRR, LOGL_ERROR, "PagingRequest with wrong MI\n");
+ return -1;
+ }
+
+ if (mi_type != GSM_MI_TYPE_NONE) {
+ gsm48_mi_to_string(mi_string, sizeof(mi_string), &pag->data[1], len1);
+ LOGP(DRR, LOGL_NOTICE, "Paging1: %s chan %s to %s M(%s) \n",
+ pag_print_mode(pag->pag_mode),
+ chan_need(pag->cneed1),
+ mi_type_to_string(mi_type),
+ mi_string);
+ }
+
+ /* check if we have a MI type in here */
+ if (msgb_l3len(msg) < sizeof(*pag) + 2 + len1 + 3)
+ return 0;
+
+ tag = pag->data[2 + len1 + 0];
+ len2 = pag->data[2 + len1 + 1];
+ mi_type = pag->data[2 + len1 + 2] & GSM_MI_TYPE_MASK;
+ if (tag == GSM48_IE_MOBILE_ID && mi_type != GSM_MI_TYPE_NONE) {
+ if (msgb_l3len(msg) < sizeof(*pag) + 2 + len1 + 3 + len2) {
+ LOGP(DRR, LOGL_ERROR, "Optional MI does not fit here.\n");
+ return -1;
+ }
+
+ gsm48_mi_to_string(mi_string, sizeof(mi_string), &pag->data[2 + len1 + 2], len2);
+ LOGP(DRR, LOGL_NOTICE, "Paging2: %s chan %s to %s M(%s) \n",
+ pag_print_mode(pag->pag_mode),
+ chan_need(pag->cneed2),
+ mi_type_to_string(mi_type),
+ mi_string);
+ }
+ return 0;
+}
+
int gsm48_rx_ccch(struct msgb *msg, struct osmocom_ms *ms)
{
struct gsm48_system_information_type_header *sih = msgb_l3(msg);
@@ -236,9 +343,13 @@ int gsm48_rx_ccch(struct msgb *msg, struct osmocom_ms *ms)
switch (sih->system_information) {
case GSM48_MT_RR_PAG_REQ_1:
+ gsm48_rx_paging_p1(msg, ms);
+ break;
case GSM48_MT_RR_PAG_REQ_2:
+ LOGP(DRR, LOGL_ERROR, "PAGING of type 2 is not implemented.\n");
+ break;
case GSM48_MT_RR_PAG_REQ_3:
- /* FIXME: implement decoding of paging request */
+ LOGP(DRR, LOGL_ERROR, "PAGING of type 3 is not implemented.\n");
break;
case GSM48_MT_RR_IMM_ASS:
gsm48_rx_imm_ass(msg, ms);