From patchwork Tue Mar 15 12:28:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neels Hofmeyr X-Patchwork-Id: 597488 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.osmocom.org (lists.osmocom.org [IPv6:2a01:4f8:191:444b::2:7]) by ozlabs.org (Postfix) with ESMTP id 3qPYvM151Tz9s0M for ; Tue, 15 Mar 2016 23:33:51 +1100 (AEDT) Received: from lists.osmocom.org (lists.osmocom.org [144.76.43.76]) by lists.osmocom.org (Postfix) with ESMTP id 255431BC51; Tue, 15 Mar 2016 12:33:49 +0000 (UTC) X-Original-To: openbsc@lists.osmocom.org Delivered-To: openbsc@lists.osmocom.org Received: from einhorn.in-berlin.de (einhorn.in-berlin.de [IPv6:2001:bf0:c000::1:8]) by lists.osmocom.org (Postfix) with ESMTP id AF21C1BC4A for ; Tue, 15 Mar 2016 12:33:47 +0000 (UTC) X-Envelope-From: nhofmeyr@sysmocom.de X-Envelope-To: Received: from localhost (ip5b418565.dynamic.kabel-deutschland.de [91.65.133.101]) (authenticated bits=0) by einhorn.in-berlin.de (8.14.4/8.14.4/Debian-4) with ESMTP id u2FCXjNk006398 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 15 Mar 2016 13:33:46 +0100 From: Neels Hofmeyr To: openbsc@lists.osmocom.org Subject: [PATCH] gsm48: factor out MCC+MNC BCD parsing for re-use in UMTS Date: Tue, 15 Mar 2016 13:28:10 +0100 Message-Id: <1458044890-3541-1-git-send-email-nhofmeyr@sysmocom.de> X-Mailer: git-send-email 2.1.4 X-BeenThere: openbsc@lists.osmocom.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "Development of OpenBSC, OsmoBSC, OsmoNITB, OsmoCSCN" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openbsc-bounces@lists.osmocom.org Sender: "OpenBSC" For 3G, I need a BCD composer/parser similar to gsm48_generate_lai()/ gsm48_decode_lai(). Those functions also handle a trivial extra member (lac) which I don't need in this way for 3G. So create new functions to take on the MCC+MNC BCD handling and call those from gsm48_generate_lai() and gsm48_decode_lai(). In this way, the 3G code in openbsc can use only the BCD functionality without code duplication. --- include/osmocom/gsm/gsm48.h | 3 +++ src/gsm/gsm48.c | 55 ++++++++++++++++++++++++++++----------------- src/gsm/libosmogsm.map | 2 ++ 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/include/osmocom/gsm/gsm48.h b/include/osmocom/gsm/gsm48.h index 74ac52c..d6e58c2 100644 --- a/include/osmocom/gsm/gsm48.h +++ b/include/osmocom/gsm/gsm48.h @@ -39,3 +39,6 @@ void gsm48_parse_ra(struct gprs_ra_id *raid, const uint8_t *buf); int gsm48_construct_ra(uint8_t *buf, const struct gprs_ra_id *raid); int gsm48_number_of_paging_subchannels(struct gsm48_control_channel_descr *chan_desc); + +void gsm48_mcc_mnc_to_bcd(uint8_t *bcd_dst, uint16_t mcc, uint16_t mnc); +void gsm48_mcc_mnc_from_bcd(uint8_t *bcd_src, uint16_t *mcc, uint16_t *mnc); diff --git a/src/gsm/gsm48.c b/src/gsm/gsm48.c index 60937cb..d0a2286 100644 --- a/src/gsm/gsm48.c +++ b/src/gsm/gsm48.c @@ -278,25 +278,50 @@ static void to_bcd(uint8_t *bcd, uint16_t val) val = val / 10; } -void gsm48_generate_lai(struct gsm48_loc_area_id *lai48, uint16_t mcc, - uint16_t mnc, uint16_t lac) +/* Convert given mcc and mnc to BCD and write to *bcd_dst, which must be an + * allocated buffer of (at least) 3 bytes length. */ +void gsm48_mcc_mnc_to_bcd(uint8_t *bcd_dst, uint16_t mcc, uint16_t mnc) { uint8_t bcd[3]; to_bcd(bcd, mcc); - lai48->digits[0] = bcd[0] | (bcd[1] << 4); - lai48->digits[1] = bcd[2]; + bcd_dst[0] = bcd[0] | (bcd[1] << 4); + bcd_dst[1] = bcd[2]; to_bcd(bcd, mnc); /* FIXME: do we need three-digit MNC? See Table 10.5.3 */ if (mnc > 99) { - lai48->digits[1] |= bcd[2] << 4; - lai48->digits[2] = bcd[0] | (bcd[1] << 4); + bcd_dst[1] |= bcd[2] << 4; + bcd_dst[2] = bcd[0] | (bcd[1] << 4); + } else { + bcd_dst[1] |= 0xf << 4; + bcd_dst[2] = bcd[1] | (bcd[2] << 4); + } +} + +/* Convert given 3-byte BCD buffer to integers and write results to *mcc and + * *mnc. The first three BCD digits result in the MCC and the remaining ones in + * the MNC. */ +void gsm48_mcc_mnc_from_bcd(uint8_t *bcd_src, uint16_t *mcc, uint16_t *mnc) +{ + *mcc = (bcd_src[0] & 0x0f) * 100 + + (bcd_src[0] >> 4) * 10 + + (bcd_src[1] & 0x0f); + + if ((bcd_src[1] & 0xf0) == 0xf0) { + *mnc = (bcd_src[2] & 0x0f) * 10 + + (bcd_src[2] >> 4); } else { - lai48->digits[1] |= 0xf << 4; - lai48->digits[2] = bcd[1] | (bcd[2] << 4); + *mnc = (bcd_src[2] & 0x0f) * 100 + + (bcd_src[2] >> 4) * 10 + + (bcd_src[1] >> 4); } +} +void gsm48_generate_lai(struct gsm48_loc_area_id *lai48, uint16_t mcc, + uint16_t mnc, uint16_t lac) +{ + gsm48_mcc_mnc_to_bcd(&lai48->digits[0], mcc, mnc); lai48->lac = htons(lac); } @@ -304,20 +329,8 @@ void gsm48_generate_lai(struct gsm48_loc_area_id *lai48, uint16_t mcc, int gsm48_decode_lai(struct gsm48_loc_area_id *lai, uint16_t *mcc, uint16_t *mnc, uint16_t *lac) { - *mcc = (lai->digits[0] & 0x0f) * 100 - + (lai->digits[0] >> 4) * 10 - + (lai->digits[1] & 0x0f); - - if ((lai->digits[1] & 0xf0) == 0xf0) { - *mnc = (lai->digits[2] & 0x0f) * 10 - + (lai->digits[2] >> 4); - } else { - *mnc = (lai->digits[2] & 0x0f) * 100 - + (lai->digits[2] >> 4) * 10 - + (lai->digits[1] >> 4); - } + gsm48_mcc_mnc_from_bcd(&lai->digits[0], mcc, mnc); *lac = ntohs(lai->lac); - return 0; } diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 7eebe7f..0aeefbb 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -138,6 +138,8 @@ gsm48_number_of_paging_subchannels; gsm48_parse_ra; gsm48_rr_att_tlvdef; gsm48_mi_type_name; +gsm48_mcc_mnc_to_bcd; +gsm48_mcc_mnc_from_bcd; gsm_7bit_decode; gsm_7bit_decode_ussd;