vty: integration with logging framework
[osmocom-bb.git] / src / gsm48_ie.c
1 /* GSM Mobile Radio Interface Layer 3 messages
2  * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
3
4 /* (C) 2008 by Harald Welte <laforge@gnumonks.org>
5  * (C) 2009-2010 by Andreas Eversberg
6  *
7  * All Rights Reserved
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  *
23  */
24
25
26 #include <stdint.h>
27 #include <string.h>
28 #include <errno.h>
29
30 #include <osmocore/utils.h>
31 #include <osmocore/msgb.h>
32 #include <osmocore/tlv.h>
33 #include <osmocore/mncc.h>
34 #include <osmocore/protocol/gsm_04_08.h>
35 #include <osmocore/gsm48_ie.h>
36
37 static const char bcd_num_digits[] = {
38         '0', '1', '2', '3', '4', '5', '6', '7',
39         '8', '9', '*', '#', 'a', 'b', 'c', '\0'
40 };
41
42 /* decode a 'called/calling/connect party BCD number' as in 10.5.4.7 */
43 int gsm48_decode_bcd_number(char *output, int output_len,
44                             const uint8_t *bcd_lv, int h_len)
45 {
46         uint8_t in_len = bcd_lv[0];
47         int i;
48
49         for (i = 1 + h_len; i <= in_len; i++) {
50                 /* lower nibble */
51                 output_len--;
52                 if (output_len <= 1)
53                         break;
54                 *output++ = bcd_num_digits[bcd_lv[i] & 0xf];
55
56                 /* higher nibble */
57                 output_len--;
58                 if (output_len <= 1)
59                         break;
60                 *output++ = bcd_num_digits[bcd_lv[i] >> 4];
61         }
62         if (output_len >= 1)
63                 *output++ = '\0';
64
65         return 0;
66 }
67
68 /* convert a single ASCII character to call-control BCD */
69 static int asc_to_bcd(const char asc)
70 {
71         int i;
72
73         for (i = 0; i < ARRAY_SIZE(bcd_num_digits); i++) {
74                 if (bcd_num_digits[i] == asc)
75                         return i;
76         }
77         return -EINVAL;
78 }
79
80 /* convert a ASCII phone number to 'called/calling/connect party BCD number' */
81 int gsm48_encode_bcd_number(uint8_t *bcd_lv, uint8_t max_len,
82                       int h_len, const char *input)
83 {
84         int in_len = strlen(input);
85         int i;
86         uint8_t *bcd_cur = bcd_lv + 1 + h_len;
87
88         /* two digits per byte, plus type byte */
89         bcd_lv[0] = in_len/2 + h_len;
90         if (in_len % 2)
91                 bcd_lv[0]++;
92
93         if (bcd_lv[0] > max_len)
94                 return -EIO;
95
96         for (i = 0; i < in_len; i++) {
97                 int rc = asc_to_bcd(input[i]);
98                 if (rc < 0)
99                         return rc;
100                 if (i % 2 == 0)
101                         *bcd_cur = rc;
102                 else
103                         *bcd_cur++ |= (rc << 4);
104         }
105         /* append padding nibble in case of odd length */
106         if (i % 2)
107                 *bcd_cur++ |= 0xf0;
108
109         /* return how many bytes we used */
110         return (bcd_cur - bcd_lv);
111 }
112
113 /* decode 'bearer capability' */
114 int gsm48_decode_bearer_cap(struct gsm_mncc_bearer_cap *bcap,
115                              const uint8_t *lv)
116 {
117         uint8_t in_len = lv[0];
118         int i, s;
119
120         if (in_len < 1)
121                 return -EINVAL;
122
123         bcap->speech_ver[0] = -1; /* end of list, of maximum 7 values */
124
125         /* octet 3 */
126         bcap->transfer = lv[1] & 0x07;
127         bcap->mode = (lv[1] & 0x08) >> 3;
128         bcap->coding = (lv[1] & 0x10) >> 4;
129         bcap->radio = (lv[1] & 0x60) >> 5;
130
131         if (bcap->transfer == GSM_MNCC_BCAP_SPEECH) {
132                 i = 1;
133                 s = 0;
134                 while(!(lv[i] & 0x80)) {
135                         i++; /* octet 3a etc */
136                         if (in_len < i)
137                                 return 0;
138                         bcap->speech_ver[s++] = lv[i] & 0x0f;
139                         bcap->speech_ver[s] = -1; /* end of list */
140                         if (i == 2) /* octet 3a */
141                                 bcap->speech_ctm = (lv[i] & 0x20) >> 5;
142                         if (s == 7) /* maximum speech versions + end of list */
143                                 return 0;
144                 }
145         } else {
146                 i = 1;
147                 while (!(lv[i] & 0x80)) {
148                         i++; /* octet 3a etc */
149                         if (in_len < i)
150                                 return 0;
151                         /* ignore them */
152                 }
153                 /* FIXME: implement OCTET 4+ parsing */
154         }
155
156         return 0;
157 }
158
159 /* encode 'bearer capability' */
160 int gsm48_encode_bearer_cap(struct msgb *msg, int lv_only,
161                              const struct gsm_mncc_bearer_cap *bcap)
162 {
163         uint8_t lv[32 + 1];
164         int i = 1, s;
165
166         lv[1] = bcap->transfer;
167         lv[1] |= bcap->mode << 3;
168         lv[1] |= bcap->coding << 4;
169         lv[1] |= bcap->radio << 5;
170
171         if (bcap->transfer == GSM_MNCC_BCAP_SPEECH) {
172                 for (s = 0; bcap->speech_ver[s] >= 0; s++) {
173                         i++; /* octet 3a etc */
174                         lv[i] = bcap->speech_ver[s];
175                         if (i == 2) /* octet 3a */
176                                 lv[i] |= bcap->speech_ctm << 5;
177                 }
178                 lv[i] |= 0x80; /* last IE of octet 3 etc */
179         } else {
180                 /* FIXME: implement OCTET 4+ encoding */
181         }
182
183         lv[0] = i;
184         if (lv_only)
185                 msgb_lv_put(msg, lv[0], lv+1);
186         else
187                 msgb_tlv_put(msg, GSM48_IE_BEARER_CAP, lv[0], lv+1);
188
189         return 0;
190 }
191
192 /* decode 'call control cap' */
193 int gsm48_decode_cccap(struct gsm_mncc_cccap *ccap, const uint8_t *lv)
194 {
195         uint8_t in_len = lv[0];
196
197         if (in_len < 1)
198                 return -EINVAL;
199
200         /* octet 3 */
201         ccap->dtmf = lv[1] & 0x01;
202         ccap->pcp = (lv[1] & 0x02) >> 1;
203
204         return 0;
205 }
206
207 /* encode 'call control cap' */
208 int gsm48_encode_cccap(struct msgb *msg,
209                         const struct gsm_mncc_cccap *ccap)
210 {
211         uint8_t lv[2];
212
213         lv[0] = 1;
214         lv[1] = 0;
215         if (ccap->dtmf)
216                 lv [1] |= 0x01;
217         if (ccap->pcp)
218                 lv [1] |= 0x02;
219
220         msgb_tlv_put(msg, GSM48_IE_CC_CAP, lv[0], lv+1);
221
222         return 0;
223 }
224
225 /* decode 'called party BCD number' */
226 int gsm48_decode_called(struct gsm_mncc_number *called,
227                          const uint8_t *lv)
228 {
229         uint8_t in_len = lv[0];
230
231         if (in_len < 1)
232                 return -EINVAL;
233
234         /* octet 3 */
235         called->plan = lv[1] & 0x0f;
236         called->type = (lv[1] & 0x70) >> 4;
237
238         /* octet 4..N */
239         gsm48_decode_bcd_number(called->number, sizeof(called->number), lv, 1);
240
241         return 0;
242 }
243
244 /* encode 'called party BCD number' */
245 int gsm48_encode_called(struct msgb *msg,
246                          const struct gsm_mncc_number *called)
247 {
248         uint8_t lv[18];
249         int ret;
250
251         /* octet 3 */
252         lv[1] = 0x80; /* no extension */
253         lv[1] |= called->plan;
254         lv[1] |= called->type << 4;
255
256         /* octet 4..N, octet 2 */
257         ret = gsm48_encode_bcd_number(lv, sizeof(lv), 1, called->number);
258         if (ret < 0)
259                 return ret;
260
261         msgb_tlv_put(msg, GSM48_IE_CALLED_BCD, lv[0], lv+1);
262
263         return 0;
264 }
265
266 /* decode callerid of various IEs */
267 int gsm48_decode_callerid(struct gsm_mncc_number *callerid,
268                          const uint8_t *lv)
269 {
270         uint8_t in_len = lv[0];
271         int i = 1;
272
273         if (in_len < 1)
274                 return -EINVAL;
275
276         /* octet 3 */
277         callerid->plan = lv[1] & 0x0f;
278         callerid->type = (lv[1] & 0x70) >> 4;
279
280         /* octet 3a */
281         if (!(lv[1] & 0x80)) {
282                 callerid->screen = lv[2] & 0x03;
283                 callerid->present = (lv[2] & 0x60) >> 5;
284                 i = 2;
285         }
286
287         /* octet 4..N */
288         gsm48_decode_bcd_number(callerid->number, sizeof(callerid->number), lv, i);
289
290         return 0;
291 }
292
293 /* encode callerid of various IEs */
294 int gsm48_encode_callerid(struct msgb *msg, int ie, int max_len,
295                            const struct gsm_mncc_number *callerid)
296 {
297         uint8_t lv[max_len - 1];
298         int h_len = 1;
299         int ret;
300
301         /* octet 3 */
302         lv[1] = callerid->plan;
303         lv[1] |= callerid->type << 4;
304
305         if (callerid->present || callerid->screen) {
306                 /* octet 3a */
307                 lv[2] = callerid->screen;
308                 lv[2] |= callerid->present << 5;
309                 lv[2] |= 0x80;
310                 h_len++;
311         } else
312                 lv[1] |= 0x80;
313
314         /* octet 4..N, octet 2 */
315         ret = gsm48_encode_bcd_number(lv, sizeof(lv), h_len, callerid->number);
316         if (ret < 0)
317                 return ret;
318
319         msgb_tlv_put(msg, ie, lv[0], lv+1);
320
321         return 0;
322 }
323
324 /* decode 'cause' */
325 int gsm48_decode_cause(struct gsm_mncc_cause *cause,
326                         const uint8_t *lv)
327 {
328         uint8_t in_len = lv[0];
329         int i;
330
331         if (in_len < 2)
332                 return -EINVAL;
333
334         cause->diag_len = 0;
335
336         /* octet 3 */
337         cause->location = lv[1] & 0x0f;
338         cause->coding = (lv[1] & 0x60) >> 5;
339
340         i = 1;
341         if (!(lv[i] & 0x80)) {
342                 i++; /* octet 3a */
343                 if (in_len < i+1)
344                         return 0;
345                 cause->rec = 1;
346                 cause->rec_val = lv[i] & 0x7f;
347         }
348         i++;
349
350         /* octet 4 */
351         cause->value = lv[i] & 0x7f;
352         i++;
353
354         if (in_len < i) /* no diag */
355                 return 0;
356
357         if (in_len - (i-1) > 32) /* maximum 32 octets */
358                 return 0;
359
360         /* octet 5-N */
361         memcpy(cause->diag, lv + i, in_len - (i-1));
362         cause->diag_len = in_len - (i-1);
363
364         return 0;
365 }
366
367 /* encode 'cause' */
368 int gsm48_encode_cause(struct msgb *msg, int lv_only,
369                         const struct gsm_mncc_cause *cause)
370 {
371         uint8_t lv[32+4];
372         int i;
373
374         if (cause->diag_len > 32)
375                 return -EINVAL;
376
377         /* octet 3 */
378         lv[1] = cause->location;
379         lv[1] |= cause->coding << 5;
380
381         i = 1;
382         if (cause->rec) {
383                 i++; /* octet 3a */
384                 lv[i] = cause->rec_val;
385         }
386         lv[i] |= 0x80; /* end of octet 3 */
387
388         /* octet 4 */
389         i++;
390         lv[i] = 0x80 | cause->value;
391
392         /* octet 5-N */
393         if (cause->diag_len) {
394                 memcpy(lv + i, cause->diag, cause->diag_len);
395                 i += cause->diag_len;
396         }
397
398         lv[0] = i;
399         if (lv_only)
400                 msgb_lv_put(msg, lv[0], lv+1);
401         else
402                 msgb_tlv_put(msg, GSM48_IE_CAUSE, lv[0], lv+1);
403
404         return 0;
405 }
406
407 /* decode 'calling number' */
408 int gsm48_decode_calling(struct gsm_mncc_number *calling,
409                          const uint8_t *lv)
410 {
411         return gsm48_decode_callerid(calling, lv);
412 }
413
414 /* encode 'calling number' */
415 int gsm48_encode_calling(struct msgb *msg, 
416                           const struct gsm_mncc_number *calling)
417 {
418         return gsm48_encode_callerid(msg, GSM48_IE_CALLING_BCD, 14, calling);
419 }
420
421 /* decode 'connected number' */
422 int gsm48_decode_connected(struct gsm_mncc_number *connected,
423                          const uint8_t *lv)
424 {
425         return gsm48_decode_callerid(connected, lv);
426 }
427
428 /* encode 'connected number' */
429 int gsm48_encode_connected(struct msgb *msg,
430                             const struct gsm_mncc_number *connected)
431 {
432         return gsm48_encode_callerid(msg, GSM48_IE_CONN_BCD, 14, connected);
433 }
434
435 /* decode 'redirecting number' */
436 int gsm48_decode_redirecting(struct gsm_mncc_number *redirecting,
437                          const uint8_t *lv)
438 {
439         return gsm48_decode_callerid(redirecting, lv);
440 }
441
442 /* encode 'redirecting number' */
443 int gsm48_encode_redirecting(struct msgb *msg,
444                               const struct gsm_mncc_number *redirecting)
445 {
446         return gsm48_encode_callerid(msg, GSM48_IE_REDIR_BCD, 19, redirecting);
447 }
448
449 /* decode 'facility' */
450 int gsm48_decode_facility(struct gsm_mncc_facility *facility,
451                            const uint8_t *lv)
452 {
453         uint8_t in_len = lv[0];
454
455         if (in_len < 1)
456                 return -EINVAL;
457
458         if (in_len > sizeof(facility->info))
459                 return -EINVAL;
460
461         memcpy(facility->info, lv+1, in_len);
462         facility->len = in_len;
463
464         return 0;
465 }
466
467 /* encode 'facility' */
468 int gsm48_encode_facility(struct msgb *msg, int lv_only,
469                            const struct gsm_mncc_facility *facility)
470 {
471         uint8_t lv[GSM_MAX_FACILITY + 1];
472
473         if (facility->len < 1 || facility->len > GSM_MAX_FACILITY)
474                 return -EINVAL;
475
476         memcpy(lv+1, facility->info, facility->len);
477         lv[0] = facility->len;
478         if (lv_only)
479                 msgb_lv_put(msg, lv[0], lv+1);
480         else
481                 msgb_tlv_put(msg, GSM48_IE_FACILITY, lv[0], lv+1);
482
483         return 0;
484 }
485
486 /* decode 'notify' */
487 int gsm48_decode_notify(int *notify, const uint8_t *v)
488 {
489         *notify = v[0] & 0x7f;
490
491         return 0;
492 }
493
494 /* encode 'notify' */
495 int gsm48_encode_notify(struct msgb *msg, int notify)
496 {
497         msgb_v_put(msg, notify | 0x80);
498
499         return 0;
500 }
501
502 /* decode 'signal' */
503 int gsm48_decode_signal(int *signal, const uint8_t *v)
504 {
505         *signal = v[0];
506
507         return 0;
508 }
509
510 /* encode 'signal' */
511 int gsm48_encode_signal(struct msgb *msg, int signal)
512 {
513         msgb_tv_put(msg, GSM48_IE_SIGNAL, signal);
514
515         return 0;
516 }
517
518 /* decode 'keypad' */
519 int gsm48_decode_keypad(int *keypad, const uint8_t *lv)
520 {
521         uint8_t in_len = lv[0];
522
523         if (in_len < 1)
524                 return -EINVAL;
525
526         *keypad = lv[1] & 0x7f;
527
528         return 0;
529 }
530
531 /* encode 'keypad' */
532 int gsm48_encode_keypad(struct msgb *msg, int keypad)
533 {
534         msgb_tv_put(msg, GSM48_IE_KPD_FACILITY, keypad);
535
536         return 0;
537 }
538
539 /* decode 'progress' */
540 int gsm48_decode_progress(struct gsm_mncc_progress *progress,
541                            const uint8_t *lv)
542 {
543         uint8_t in_len = lv[0];
544
545         if (in_len < 2)
546                 return -EINVAL;
547
548         progress->coding = (lv[1] & 0x60) >> 5;
549         progress->location = lv[1] & 0x0f;
550         progress->descr = lv[2] & 0x7f;
551
552         return 0;
553 }
554
555 /* encode 'progress' */
556 int gsm48_encode_progress(struct msgb *msg, int lv_only,
557                            const struct gsm_mncc_progress *p)
558 {
559         uint8_t lv[3];
560
561         lv[0] = 2;
562         lv[1] = 0x80 | ((p->coding & 0x3) << 5) | (p->location & 0xf);
563         lv[2] = 0x80 | (p->descr & 0x7f);
564         if (lv_only)
565                 msgb_lv_put(msg, lv[0], lv+1);
566         else
567                 msgb_tlv_put(msg, GSM48_IE_PROGR_IND, lv[0], lv+1);
568
569         return 0;
570 }
571
572 /* decode 'user-user' */
573 int gsm48_decode_useruser(struct gsm_mncc_useruser *uu,
574                            const uint8_t *lv)
575 {
576         uint8_t in_len = lv[0];
577         char *info = uu->info;
578         int info_len = sizeof(uu->info);
579         int i;
580
581         if (in_len < 1)
582                 return -EINVAL;
583
584         uu->proto = lv[1];
585
586         for (i = 2; i <= in_len; i++) {
587                 info_len--;
588                 if (info_len <= 1)
589                         break;
590                 *info++ = lv[i];
591         }
592         if (info_len >= 1)
593                 *info++ = '\0';
594
595         return 0;
596 }
597
598 /* encode 'useruser' */
599 int gsm48_encode_useruser(struct msgb *msg, int lv_only,
600                            const struct gsm_mncc_useruser *uu)
601 {
602         uint8_t lv[GSM_MAX_USERUSER + 2];
603
604         if (strlen(uu->info) > GSM_MAX_USERUSER)
605                 return -EINVAL;
606
607         lv[0] = 1 + strlen(uu->info);
608         lv[1] = uu->proto;
609         memcpy(lv + 2, uu->info, strlen(uu->info));
610         if (lv_only)
611                 msgb_lv_put(msg, lv[0], lv+1);
612         else
613                 msgb_tlv_put(msg, GSM48_IE_USER_USER, lv[0], lv+1);
614
615         return 0;
616 }
617
618 /* decode 'ss version' */
619 int gsm48_decode_ssversion(struct gsm_mncc_ssversion *ssv,
620                             const uint8_t *lv)
621 {
622         uint8_t in_len = lv[0];
623
624         if (in_len < 1 || in_len < sizeof(ssv->info))
625                 return -EINVAL;
626
627         memcpy(ssv->info, lv + 1, in_len);
628         ssv->len = in_len;
629
630         return 0;
631 }
632
633 /* encode 'ss version' */
634 int gsm48_encode_ssversion(struct msgb *msg,
635                            const struct gsm_mncc_ssversion *ssv)
636 {
637         uint8_t lv[GSM_MAX_SSVERSION + 1];
638
639         if (ssv->len > GSM_MAX_SSVERSION)
640                 return -EINVAL;
641
642         lv[0] = ssv->len;
643         memcpy(lv + 1, ssv->info, ssv->len);
644         msgb_tlv_put(msg, GSM48_IE_SS_VERS, lv[0], lv+1);
645
646         return 0;
647 }
648
649 /* decode 'more data' does not require a function, because it has no value */
650
651 /* encode 'more data' */
652 int gsm48_encode_more(struct msgb *msg)
653 {
654         uint8_t *ie;
655
656         ie = msgb_put(msg, 1);
657         ie[0] = GSM48_IE_MORE_DATA;
658
659         return 0;
660 }
661
662 /* decode "Cell Channel Description" (10.5.2.1b) and other frequency lists */
663 int gsm48_decode_freq_list(struct gsm_sysinfo_freq *f, uint8_t *cd,
664                            uint8_t len, uint8_t mask, uint8_t frqt)
665 {
666         int i;
667
668         /* NOTES:
669          *
670          * The Range format uses "SMOD" computation.
671          * e.g. "n SMOD m" equals "((n - 1) % m) + 1"
672          * A cascade of multiple SMOD computations is simpified:
673          * "(n SMOD m) SMOD o" equals "(((n - 1) % m) % o) + 1"
674          *
675          * The Range format uses 16 octets of data in SYSTEM INFORMATION.
676          * When used in dedicated messages, the length can be less.
677          * In this case the ranges are decoded for all frequencies that
678          * fit in the block of given length.
679          */
680
681         /* tabula rasa */
682         for (i = 0; i < 1024; i++)
683                 f[i].mask &= ~frqt;
684
685         /* 00..XXX. */
686         if ((cd[0] & 0xc0 & mask) == 0x00) {
687                 /* Bit map 0 format */
688                 if (len < 16)
689                         return -EINVAL;
690                 for (i = 1; i <= 124; i++)
691                         if ((cd[15 - ((i-1) >> 3)] & (1 << ((i-1) & 7))))
692                                 f[i].mask |= frqt;
693
694                 return 0;
695         }
696
697         /* 10..0XX. */
698         if ((cd[0] & 0xc8 & mask) == 0x80) {
699                 /* Range 1024 format */
700                 uint16_t w[17]; /* 1..16 */
701                 struct gsm48_range_1024 *r = (struct gsm48_range_1024 *)cd;
702
703                 if (len < 2)
704                         return -EINVAL;
705                 memset(w, 0, sizeof(w));
706                 if (r->f0)
707                         f[0].mask |= frqt;
708                 w[1] = (r->w1_hi << 8) | r->w1_lo;
709                 if (len >= 4)
710                         w[2] = (r->w2_hi << 1) | r->w2_lo;
711                 if (len >= 5)
712                         w[3] = (r->w3_hi << 2) | r->w3_lo;
713                 if (len >= 6)
714                         w[4] = (r->w4_hi << 2) | r->w4_lo;
715                 if (len >= 7)
716                         w[5] = (r->w5_hi << 2) | r->w5_lo;
717                 if (len >= 8)
718                         w[6] = (r->w6_hi << 2) | r->w6_lo;
719                 if (len >= 9)
720                         w[7] = (r->w7_hi << 2) | r->w7_lo;
721                 if (len >= 10)
722                         w[8] = (r->w8_hi << 1) | r->w8_lo;
723                 if (len >= 10)
724                         w[9] = r->w9;
725                 if (len >= 11)
726                         w[10] = r->w10;
727                 if (len >= 12)
728                         w[11] = (r->w11_hi << 6) | r->w11_lo;
729                 if (len >= 13)
730                         w[12] = (r->w12_hi << 5) | r->w12_lo;
731                 if (len >= 14)
732                         w[13] = (r->w13_hi << 4) | r->w13_lo;
733                 if (len >= 15)
734                         w[14] = (r->w14_hi << 3) | r->w14_lo;
735                 if (len >= 16)
736                         w[15] = (r->w15_hi << 2) | r->w15_lo;
737                 if (len >= 16)
738                         w[16] = r->w16;
739                 if (w[1])
740                         f[w[1]].mask |= frqt;
741                 if (w[2])
742                         f[((w[1] - 512 + w[2] - 1) % 1023) + 1].mask |= frqt;
743                 if (w[3])
744                         f[((w[1]       + w[3] - 1) % 1023) + 1].mask |= frqt;
745                 if (w[4])
746                         f[((w[1] - 512 + ((w[2] - 256 + w[4] - 1) % 511)) % 1023) + 1].mask |= frqt;
747                 if (w[5])
748                         f[((w[1]       + ((w[3] - 256 - w[5] - 1) % 511)) % 1023) + 1].mask |= frqt;
749                 if (w[6])
750                         f[((w[1] - 512 + ((w[2]       + w[6] - 1) % 511)) % 1023) + 1].mask |= frqt;
751                 if (w[7])
752                         f[((w[1]       + ((w[3]       + w[7] - 1) % 511)) % 1023) + 1].mask |= frqt;
753                 if (w[8])
754                         f[((w[1] - 512 + ((w[2] - 256 + ((w[4] - 128 + w[8] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt;
755                 if (w[9])
756                         f[((w[1]       + ((w[3] - 256 + ((w[5] - 128 + w[9] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt;
757                 if (w[10])
758                         f[((w[1] - 512 + ((w[2]       + ((w[6] - 128 + w[10] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt;
759                 if (w[11])
760                         f[((w[1]       + ((w[3]       + ((w[7] - 128 + w[11] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt;
761                 if (w[12])
762                         f[((w[1] - 512 + ((w[2] - 256 + ((w[4]       + w[12] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt;
763                 if (w[13])
764                         f[((w[1]       + ((w[3] - 256 + ((w[5]       + w[13] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt;
765                 if (w[14])
766                         f[((w[1] - 512 + ((w[2]       + ((w[6]       + w[14] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt;
767                 if (w[15])
768                         f[((w[1]       + ((w[3]       + ((w[7]       + w[15] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt;
769                 if (w[16])
770                         f[((w[1] - 512 + ((w[2] - 256 + ((w[4] - 128 + ((w[8] - 64 + w[16] - 1) % 127)) % 255)) % 511)) % 1023) + 1].mask |= frqt;
771
772                 return 0;
773         }
774         /* 10..100. */
775         if ((cd[0] & 0xce & mask) == 0x88) {
776                 /* Range 512 format */
777                 uint16_t w[18]; /* 1..17 */
778                 struct gsm48_range_512 *r = (struct gsm48_range_512 *)cd;
779
780                 if (len < 4)
781                         return -EINVAL;
782                 memset(w, 0, sizeof(w));
783                 w[0] = (r->orig_arfcn_hi << 9) | (r->orig_arfcn_mid << 1) | r->orig_arfcn_lo;
784                 w[1] = (r->w1_hi << 2) | r->w1_lo;
785                 if (len >= 5)
786                         w[2] = (r->w2_hi << 2) | r->w2_lo;
787                 if (len >= 6)
788                         w[3] = (r->w3_hi << 2) | r->w3_lo;
789                 if (len >= 7)
790                         w[4] = (r->w4_hi << 1) | r->w4_lo;
791                 if (len >= 7)
792                         w[5] = r->w5;
793                 if (len >= 8)
794                         w[6] = r->w6;
795                 if (len >= 9)
796                         w[7] = (r->w7_hi << 6) | r->w7_lo;
797                 if (len >= 10)
798                         w[8] = (r->w8_hi << 4) | r->w8_lo;
799                 if (len >= 11)
800                         w[9] = (r->w9_hi << 2) | r->w9_lo;
801                 if (len >= 11)
802                         w[10] = r->w10;
803                 if (len >= 12)
804                         w[11] = r->w11;
805                 if (len >= 13)
806                         w[12] = (r->w12_hi << 4) | r->w12_lo;
807                 if (len >= 14)
808                         w[13] = (r->w13_hi << 2) | r->w13_lo;
809                 if (len >= 14)
810                         w[14] = r->w14;
811                 if (len >= 15)
812                         w[15] = r->w15;
813                 if (len >= 16)
814                         w[16] = (r->w16_hi << 3) | r->w16_lo;
815                 if (len >= 16)
816                         w[17] = r->w17;
817                 f[w[0]].mask |= frqt;
818                 if (w[1])
819                         f[(w[0] + w[1]) % 1024].mask |= frqt;
820                 if (w[2])
821                         f[(w[0] + ((w[1] - 256 + w[2] - 1) % 511) + 1) % 1024].mask |= frqt;
822                 if (w[3])
823                         f[(w[0] + ((w[1]       + w[3] - 1) % 511) + 1) % 1024].mask |= frqt;
824                 if (w[4])
825                         f[(w[0] + ((w[1] - 256 + ((w[2] - 128 + w[4] - 1) % 255)) % 511) + 1) % 1024].mask |= frqt;
826                 if (w[5])
827                         f[(w[0] + ((w[1]       + ((w[3] - 128 + w[5] - 1) % 255)) % 511) + 1) % 1024].mask |= frqt;
828                 if (w[6])
829                         f[(w[0] + ((w[1] - 256 + ((w[2]       + w[6] - 1) % 255)) % 511) + 1) % 1024].mask |= frqt;
830                 if (w[7])
831                         f[(w[0] + ((w[1]       + ((w[3]       + w[7] - 1) % 255)) % 511) + 1) % 1024].mask |= frqt;
832                 if (w[8])
833                         f[(w[0] + ((w[1] - 256 + ((w[2] - 128 + ((w[4] - 64 + w[8] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
834                 if (w[9])
835                         f[(w[0] + ((w[1]       + ((w[3] - 128 + ((w[5] - 64 + w[9] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
836                 if (w[10])
837                         f[(w[0] + ((w[1] - 256 + ((w[2]       + ((w[6] - 64 + w[10] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
838                 if (w[11])
839                         f[(w[0] + ((w[1]       + ((w[3]       + ((w[7] - 64 + w[11] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
840                 if (w[12])
841                         f[(w[0] + ((w[1] - 256 + ((w[2] - 128 + ((w[4]      + w[12] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
842                 if (w[13])
843                         f[(w[0] + ((w[1]       + ((w[3] - 128 + ((w[5]      + w[13] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
844                 if (w[14])
845                         f[(w[0] + ((w[1] - 256 + ((w[2]       + ((w[6]      + w[14] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
846                 if (w[15])
847                         f[(w[0] + ((w[1]       + ((w[3]       + ((w[7]      + w[15] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
848                 if (w[16])
849                         f[(w[0] + ((w[1] - 256 + ((w[2] - 128 + ((w[4] - 64 + ((w[8] - 32 + w[16] - 1) % 63)) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
850                 if (w[17])
851                         f[(w[0] + ((w[1]       + ((w[3] - 128 + ((w[5] - 64 + ((w[9] - 32 + w[17] - 1) % 63)) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
852
853                 return 0;
854         }
855         /* 10..101. */
856         if ((cd[0] & 0xce & mask) == 0x8a) {
857                 /* Range 256 format */
858                 uint16_t w[22]; /* 1..21 */
859                 struct gsm48_range_256 *r = (struct gsm48_range_256 *)cd;
860
861                 if (len < 4)
862                         return -EINVAL;
863                 memset(w, 0, sizeof(w));
864                 w[0] = (r->orig_arfcn_hi << 9) | (r->orig_arfcn_mid << 1) | r->orig_arfcn_lo;
865                 w[1] = (r->w1_hi << 1) | r->w1_lo;
866                 if (len >= 4)
867                         w[2] = r->w2;
868                 if (len >= 5)
869                         w[3] = r->w3;
870                 if (len >= 6)
871                         w[4] = (r->w4_hi << 5) | r->w4_lo;
872                 if (len >= 7)
873                         w[5] = (r->w5_hi << 3) | r->w5_lo;
874                 if (len >= 8)
875                         w[6] = (r->w6_hi << 1) | r->w6_lo;
876                 if (len >= 8)
877                         w[7] = r->w7;
878                 if (len >= 9)
879                         w[8] = (r->w8_hi << 4) | r->w8_lo;
880                 if (len >= 10)
881                         w[9] = (r->w9_hi << 1) | r->w9_lo;
882                 if (len >= 10)
883                         w[10] = r->w10;
884                 if (len >= 11)
885                         w[11] = (r->w11_hi << 3) | r->w11_lo;
886                 if (len >= 11)
887                         w[12] = r->w12;
888                 if (len >= 12)
889                         w[13] = r->w13;
890                 if (len >= 13)
891                         w[14] = r->w15;
892                 if (len >= 13)
893                         w[15] = (r->w14_hi << 2) | r->w14_lo;
894                 if (len >= 14)
895                         w[16] = (r->w16_hi << 3) | r->w16_lo;
896                 if (len >= 14)
897                         w[17] = r->w17;
898                 if (len >= 15)
899                         w[18] = r->w19;
900                 if (len >= 15)
901                         w[19] = (r->w18_hi << 3) | r->w18_lo;
902                 if (len >= 16)
903                         w[20] = (r->w20_hi << 3) | r->w20_lo;
904                 if (len >= 16)
905                         w[21] = r->w21;
906                 f[w[0]].mask |= frqt;
907                 if (w[1])
908                         f[(w[0] + w[1]) % 1024].mask |= frqt;
909                 if (w[2])
910                         f[(w[0] + ((w[1] - 128 + w[2] - 1) % 255) + 1) % 1024].mask |= frqt;
911                 if (w[3])
912                         f[(w[0] + ((w[1]       + w[3] - 1) % 255) + 1) % 1024].mask |= frqt;
913                 if (w[4])
914                         f[(w[0] + ((w[1] - 128 + ((w[2] - 64 + w[4] - 1) % 127)) % 255) + 1) % 1024].mask |= frqt;
915                 if (w[5])
916                         f[(w[0] + ((w[1]       + ((w[3] - 64 + w[5] - 1) % 127)) % 255) + 1) % 1024].mask |= frqt;
917                 if (w[6])
918                         f[(w[0] + ((w[1] - 128 + ((w[2]      + w[6] - 1) % 127)) % 255) + 1) % 1024].mask |= frqt;
919                 if (w[7])
920                         f[(w[0] + ((w[1]       + ((w[3]      + w[7] - 1) % 127)) % 255) + 1) % 1024].mask |= frqt;
921                 if (w[8])
922                         f[(w[0] + ((w[1] - 128 + ((w[2] - 64 + ((w[4] - 32 + w[8] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
923                 if (w[9])
924                         f[(w[0] + ((w[1]       + ((w[3] - 64 + ((w[5] - 32 + w[9] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
925                 if (w[10])
926                         f[(w[0] + ((w[1] - 128 + ((w[2]      + ((w[6] - 32 + w[10] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
927                 if (w[11])
928                         f[(w[0] + ((w[1]       + ((w[3]      + ((w[7] - 32 + w[11] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
929                 if (w[12])
930                         f[(w[0] + ((w[1] - 128 + ((w[2] - 64 + ((w[4]      + w[12] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
931                 if (w[13])
932                         f[(w[0] + ((w[1]       + ((w[3] - 64 + ((w[5]      + w[13] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
933                 if (w[14])
934                         f[(w[0] + ((w[1] - 128 + ((w[2]      + ((w[6]      + w[14] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
935                 if (w[15])
936                         f[(w[0] + ((w[1]       + ((w[3]      + ((w[7]      + w[15] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
937                 if (w[16])
938                         f[(w[0] + ((w[1] - 128 + ((w[2] - 64 + ((w[4] - 32 + ((w[8] - 16 + w[16] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
939                 if (w[17])
940                         f[(w[0] + ((w[1]       + ((w[3] - 64 + ((w[5] - 32 + ((w[9] - 16 + w[17] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
941                 if (w[18])
942                         f[(w[0] + ((w[1] - 128 + ((w[2]      + ((w[6] - 32 + ((w[10] - 16 + w[18] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
943                 if (w[19])
944                         f[(w[0] + ((w[1]       + ((w[3]      + ((w[7] - 32 + ((w[11] - 16 + w[19] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
945                 if (w[20])
946                         f[(w[0] + ((w[1] - 128 + ((w[2] - 64 + ((w[4]      + ((w[12] - 16 + w[20] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
947                 if (w[21])
948                         f[(w[0] + ((w[1]       + ((w[3] - 64 + ((w[5]      + ((w[13] - 16 + w[21] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
949
950                 return 0;
951         }
952         /* 10..110. */
953         if ((cd[0] & 0xce & mask) == 0x8c) {
954                 /* Range 128 format */
955                 uint16_t w[29]; /* 1..28 */
956                 struct gsm48_range_128 *r = (struct gsm48_range_128 *)cd;
957
958                 if (len < 3)
959                         return -EINVAL;
960                 memset(w, 0, sizeof(w));
961                 w[0] = (r->orig_arfcn_hi << 9) | (r->orig_arfcn_mid << 1) | r->orig_arfcn_lo;
962                 w[1] = r->w1;
963                 if (len >= 4)
964                         w[2] = r->w2;
965                 if (len >= 5)
966                         w[3] = (r->w3_hi << 4) | r->w3_lo;
967                 if (len >= 6)
968                         w[4] = (r->w4_hi << 1) | r->w4_lo;
969                 if (len >= 6)
970                         w[5] = r->w5;
971                 if (len >= 7)
972                         w[6] = (r->w6_hi << 3) | r->w6_lo;
973                 if (len >= 7)
974                         w[7] = r->w7;
975                 if (len >= 8)
976                         w[8] = r->w8;
977                 if (len >= 8)
978                         w[9] = r->w9;
979                 if (len >= 9)
980                         w[10] = r->w10;
981                 if (len >= 9)
982                         w[11] = r->w11;
983                 if (len >= 10)
984                         w[12] = r->w12;
985                 if (len >= 10)
986                         w[13] = r->w13;
987                 if (len >= 11)
988                         w[14] = r->w14;
989                 if (len >= 11)
990                         w[15] = r->w15;
991                 if (len >= 12)
992                         w[16] = r->w16;
993                 if (len >= 12)
994                         w[17] = r->w17;
995                 if (len >= 13)
996                         w[18] = (r->w18_hi << 1) | r->w18_lo;
997                 if (len >= 13)
998                         w[19] = r->w19;
999                 if (len >= 13)
1000                         w[20] = r->w20;
1001                 if (len >= 14)
1002                         w[21] = (r->w21_hi << 2) | r->w21_lo;
1003                 if (len >= 14)
1004                         w[22] = r->w22;
1005                 if (len >= 14)
1006                         w[23] = r->w23;
1007                 if (len >= 15)
1008                         w[24] = r->w24;
1009                 if (len >= 15)
1010                         w[25] = r->w25;
1011                 if (len >= 16)
1012                         w[26] = (r->w26_hi << 1) | r->w26_lo;
1013                 if (len >= 16)
1014                         w[27] = r->w27;
1015                 if (len >= 16)
1016                         w[28] = r->w28;
1017                 f[w[0]].mask |= frqt;
1018                 if (w[1])
1019                         f[(w[0] + w[1]) % 1024].mask |= frqt;
1020                 if (w[2])
1021                         f[(w[0] + ((w[1] - 64 + w[2] - 1) % 127) + 1) % 1024].mask |= frqt;
1022                 if (w[3])
1023                         f[(w[0] + ((w[1]      + w[3] - 1) % 127) + 1) % 1024].mask |= frqt;
1024                 if (w[4])
1025                         f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + w[4] - 1) % 63)) % 127) + 1) % 1024].mask |= frqt;
1026                 if (w[5])
1027                         f[(w[0] + ((w[1]      + ((w[3] - 32 + w[5] - 1) % 63)) % 127) + 1) % 1024].mask |= frqt;
1028                 if (w[6])
1029                         f[(w[0] + ((w[1] - 64 + ((w[2]      + w[6] - 1) % 63)) % 127) + 1) % 1024].mask |= frqt;
1030                 if (w[7])
1031                         f[(w[0] + ((w[1]      + ((w[3]      + w[7] - 1) % 63)) % 127) + 1) % 1024].mask |= frqt;
1032                 if (w[8])
1033                         f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4] - 16 + w[8] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1034                 if (w[9])
1035                         f[(w[0] + ((w[1]      + ((w[3] - 32 + ((w[5] - 16 + w[9] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1036                 if (w[10])
1037                         f[(w[0] + ((w[1] - 64 + ((w[2]      + ((w[6] - 16 + w[10] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1038                 if (w[11])
1039                         f[(w[0] + ((w[1]      + ((w[3]      + ((w[7] - 16 + w[11] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1040                 if (w[12])
1041                         f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4]      + w[12] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1042                 if (w[13])
1043                         f[(w[0] + ((w[1]      + ((w[3] - 32 + ((w[5]      + w[13] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1044                 if (w[14])
1045                         f[(w[0] + ((w[1] - 64 + ((w[2]      + ((w[6]      + w[14] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1046                 if (w[15])
1047                         f[(w[0] + ((w[1]      + ((w[3]      + ((w[7]      + w[15] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1048                 if (w[16])
1049                         f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4] - 16 + ((w[8] - 8 + w[16] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1050                 if (w[17])
1051                         f[(w[0] + ((w[1]      + ((w[3] - 32 + ((w[5] - 16 + ((w[9] - 8 + w[17] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1052                 if (w[18])
1053                         f[(w[0] + ((w[1] - 64 + ((w[2]      + ((w[6] - 16 + ((w[10] - 8 + w[18] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1054                 if (w[19])
1055                         f[(w[0] + ((w[1]      + ((w[3]      + ((w[7] - 16 + ((w[11] - 8 + w[19] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1056                 if (w[20])
1057                         f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4]      + ((w[12] - 8 + w[20] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1058                 if (w[21])
1059                         f[(w[0] + ((w[1]      + ((w[3] - 32 + ((w[5]      + ((w[13] - 8 + w[21] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1060                 if (w[22])
1061                         f[(w[0] + ((w[1] - 64 + ((w[2]      + ((w[6]      + ((w[14] - 8 + w[22] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1062                 if (w[23])
1063                         f[(w[0] + ((w[1]      + ((w[3]      + ((w[7]      + ((w[15] - 8 + w[23] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1064                 if (w[24])
1065                         f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4] - 16 + ((w[8]     + w[24] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1066                 if (w[25])
1067                         f[(w[0] + ((w[1]      + ((w[3] - 32 + ((w[5] - 16 + ((w[9]     + w[25] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1068                 if (w[26])
1069                         f[(w[0] + ((w[1] - 64 + ((w[2]      + ((w[6] - 16 + ((w[10]     + w[26] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1070                 if (w[27])
1071                         f[(w[0] + ((w[1]      + ((w[3]      + ((w[7] - 16 + ((w[11]     + w[27] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1072                 if (w[28])
1073                         f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4]      + ((w[12]     + w[28] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1074
1075                 return 0;
1076         }
1077         /* 10..111. */
1078         if ((cd[0] & 0xce & mask) == 0x8e) {
1079                 /* Variable bitmap format (can be any length >= 3) */
1080                 uint16_t orig = 0;
1081                 struct gsm48_var_bit *r = (struct gsm48_var_bit *)cd;
1082
1083                 if (len < 3)
1084                         return -EINVAL;
1085                 orig = (r->orig_arfcn_hi << 9) | (r->orig_arfcn_mid << 1) | r->orig_arfcn_lo;
1086                 f[orig].mask |= frqt;
1087                 for (i = 1; 2 + (i >> 3) < len; i++)
1088                         if ((cd[2 + (i >> 3)] & (0x80 >> (i & 7))))
1089                                 f[(orig + i) % 1024].mask |= frqt;
1090
1091                 return 0;
1092         }
1093
1094         return 0;
1095 }