From 10dfc5a97daae6bbd16a10d5d2fd39e2ef77fb34 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Fri, 11 Sep 2015 01:34:45 +0200 Subject: [PATCH] respond to HNBAP UE REGISTER REQ withe correspnding ACCEPT The Accept incudes the IMSI that the phone presented, but somehow we fail to encode the Context ID as bitstring, see ../pcap/20150911-hnbap-ue_register.pcap --- pcap/20150911-hnbap-ue_register.pcap | Bin 0 -> 6712 bytes src/hnbgw.c | 2 + src/hnbgw_hnbap.c | 83 ++++++++++++++++++++++++--- 3 files changed, 78 insertions(+), 7 deletions(-) create mode 100644 pcap/20150911-hnbap-ue_register.pcap diff --git a/pcap/20150911-hnbap-ue_register.pcap b/pcap/20150911-hnbap-ue_register.pcap new file mode 100644 index 0000000000000000000000000000000000000000..9874af9b32f36deabbadad0ab16de1496e10aa34 GIT binary patch literal 6712 zcmd^^dsJ0*7RP_*KHvfuY?fp#LSqOO%*O?;1V+q}iF90CW#Zv&R=Ld3DAJK&Qmbjm zuyL4tfiHaV7(~Q!3^dEBmWZa7K#43-)0{>V5X$SQGb-bny?^%{e}{eaxaRLUYyG(A za_{->&)&c9?{UsO)>L0M5}adW54A1Y{Wc3(T61lNjir3d z5*wE=CKtv1a&Ik*ffk$R$@AbB=S|unfkJ3<{uf)AZ)F&Wd*$uShgrSKe+A`n@Fi?s zO|L#Eo1~GT3(C7!qbjPSGO7(uS#`|BBzw}Cl0GI?FjUSsS$+XjZF_68fAYSvSmw(* z)2mWTf9^<0)+C_kBDVtF2nuYRt5 z_2hZq6`EMY>ePMK*jd+81KG^Z@qH6RYhrSCPXBJzg@sf89QWNTi{iD{-Rb;3_@`0D zbonVF*hjY_?Q9TSjE(k@WNTcCeKhtp%mS;4mBi|eo5J$^+5bsxN~wMu`qiG?0I&nr*_~!*>!8HgXr0-6jmvnQxm&b#w!X09Q)Xtlc#(1h zLsw5_U{N!>-%=Rua5%;$Cya79q8$m&7{^$L%xvs|H2&pF>NP(D2Ot>pV`e{384FNG zln*n>VIU=CGk*pngOAzfVlmJ?|hZSH~GfQ5(O&&St?mHeDaN8&`0(N2pry+kg8tu*ShPIEJtdWEMFb zPc7`B5TG8!;0qR6lHmnD&yua!3vgf#4X%xnd_^Gt9M6lWQbI zJqvT$ZEw-2j>Z}uHI7EjoVc}5>90<{B0yMFb0&EEiuaekaw}x?)(KjS_ZECOfT7~^T18qFr>lflrH@ucI#=@tSX_0A zPE<@aWc-9PK1>;1y$vOTF|kf%M8!Q?MLlCFXS_)n3qprn7mPx294KCW*@*GL56BpO znKG7itZEUA86heoDyGA%d%I`!j4L_g4a&GJDt@zI6pAt^w!ENGr0#bfdY_7@dVf^p#u zl@S$>Y8Ca2t2yJpDdYK;z+}NF6eob9yTQt4z;MB)TT?PzYq;WZs(9#BU~$`683D9!-I@5?1N4SE!tZkwlU8Yb&fs@Ymad;VcAC zt<2AVhUt-k3sdG^V|H1RSs;@FVN^r3#g&rSiBW#HYXj$Rp*1c~e*6fou{@Gg0WWZP zSN3jxhPy~JuIwfreV8NW=WYw2Lm4sZ(w!3f4SW%sF2~enz7~&g(;S1$C0}Dy*m-rU zD?3CD1r5;UEtpwlzWb6OO^h_*6N}hG(EJ>(jXXb{&r9DjZB_Dvo9qe@XDkQQww<(y zm5RmT3ne&TKaXcT9I zV*8pP1OK$bjg?#!Sxgx-S4N(OTB3hIn74cS2cs311sVCLob!K0`6p}`v{$LGRjn^X z$368$h>pE^SN~vC_xnKx{%MWnIWD0&9*Q1OtoY|5@sAHg#MaM0b0E_2c_t(ORPg+8 zx5M|L>iy{D>QdOd^6}xL=2rk}AuCM={%QROat}v0_VbVZgKxGA|2!6_`Ue%~X%+SU zspNdUlyB^_Zypf-5sI&a;=0vFjNcR>laa^&!ubzU{%tpY zo1}OE?)xhs7#v=Y_rMvBvb%a5qdwPTGVu6OxI>2=chekmPyOhRQDG$Y5RXGu@XoZq z$1&3P9;=bZt9gDu()=Eq{CTUApH0ngA*fxp`51Wo=tj={IOXoR)i7H4XU-ATKd9*P z(-LR%DAa-5@NENj2d>#Zs75@MLb8HS3c;e=EOFRybO5p(; z@%W!0QYAcRNrDfs>F#74u3Da7H_b0=<(P0KKYum9WuP|xJ)?bOdpL53e?vg(0ayFd%JAKu6GG{*?nHcq75 zE6+(g-5dm3<)Co9-spFZ<71E}tWryZ@qOH}li@xybZYl!-gTe+&VkCq8jRRL7nJ)y zcSf~S7Xs42vHso8%7CpPI4A~^hD_PvjgbkG|LHX`=yAvC#CDgmm HAlrWdD&>R* literal 0 HcmV?d00001 diff --git a/src/hnbgw.c b/src/hnbgw.c index ac0d03c9..b50cd9db 100644 --- a/src/hnbgw.c +++ b/src/hnbgw.c @@ -9,6 +9,7 @@ #include #include #include +//#include #include #include @@ -245,6 +246,7 @@ int main(int argc, char **argv) g_hnb_gw.listen_fd.cb = listen_fd_cb; g_hnb_gw.listen_fd.when = BSC_FD_READ; g_hnb_gw.listen_fd.data = &g_hnb_gw; + g_hnb_gw.next_ue_ctx_id = 23; INIT_LLIST_HEAD(&g_hnb_gw.hnb_list); INIT_LLIST_HEAD(&g_hnb_gw.ue_list); diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c index d00d59e0..7810573b 100644 --- a/src/hnbgw_hnbap.c +++ b/src/hnbgw_hnbap.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -23,6 +24,51 @@ static int hnbgw_hnbap_tx(struct hnb_context *ctx, struct msgb *msg) return osmo_wqueue_enqueue(&ctx->wqueue, msg); } +int decode_iu_bcd(char *out, size_t out_len, const uint8_t *in, size_t in_len) +{ + const uint8_t *ch; + char *outch = out; + + for (ch = in; ch < in + in_len; ch++) { + char c = osmo_bcd2char(*ch & 0xF); + *outch++ = c; + if (outch + 1 >= out + out_len) + break; + c = osmo_bcd2char(*ch >> 4); + /* skip padding nibble at end */ + if (c == 'F') + break; + *outch++ = c; + } + *outch++ = '\0'; + return outch - out; +} + +int encode_iu_imsi(uint8_t *out, size_t out_len, + const char *in) +{ + unsigned int len = strlen(in); + uint8_t odd = (len & 0x01) == 1; + unsigned int off = 0; + unsigned int i; + + len /= 2; + if (odd) + len++; + + for (i = 0; i < len; i++) { + uint8_t lower, upper; + + lower = osmo_char2bcd(in[++off]) & 0x0f; + if (!odd && off + 1 == len) + upper = 0x0f; + else + upper = osmo_char2bcd(in[++off]) & 0x0f; + + out[i] = (upper << 4) | lower; + } + return i; +} static int hnbgw_tx_hnb_register_acc(struct hnb_context *ctx) { @@ -57,10 +103,15 @@ static int hnbgw_tx_ue_register_acc(struct ue_context *ue) UERegisterAccept_t accept_out; UERegisterAcceptIEs_t accept; struct msgb *msg; + uint8_t encoded_imsi[10]; + size_t encoded_imsi_len; int rc; - /* FIXME accept.uE_Identity; */ + encoded_imsi_len = encode_iu_imsi(encoded_imsi, sizeof(encoded_imsi), ue->imsi); + memset(&accept, 0, sizeof(accept)); + accept.uE_Identity.present = UE_Identity_PR_iMSI; + OCTET_STRING_fromBuf(&accept.uE_Identity.choice.iMSI, (const char *)encoded_imsi, encoded_imsi_len); asn1_u32_to_bitstring(&accept.context_ID, &ue->context_id); memset(&accept_out, 0, sizeof(accept_out)); @@ -105,19 +156,37 @@ static int hnbgw_rx_ue_register_req(struct hnb_context *ctx, ANY_t *in) { UERegisterRequestIEs_t ies; struct ue_context *ue; + char imsi[16]; int rc; rc = hnbap_decode_ueregisterrequesties(&ies, in); if (rc < 0) return rc; - /* FIXME: convert UE identity into a more palatable format */ - ue = ue_context_by_imsi("123"); - if (!ue) - ue = ue_context_alloc(ctx, "123"); + switch (ies.uE_Identity.present) { + case UE_Identity_PR_iMSI: + decode_iu_bcd(imsi, sizeof(imsi), ies.uE_Identity.choice.iMSI.buf, + ies.uE_Identity.choice.iMSI.size); + break; + case UE_Identity_PR_iMSIDS41: + decode_iu_bcd(imsi, sizeof(imsi), ies.uE_Identity.choice.iMSIDS41.buf, + ies.uE_Identity.choice.iMSIDS41.size); + break; + case UE_Identity_PR_iMSIESN: + decode_iu_bcd(imsi, sizeof(imsi), ies.uE_Identity.choice.iMSIESN.iMSIDS41.buf, + ies.uE_Identity.choice.iMSIESN.iMSIDS41.size); + break; + default: + DEBUGP(DMAIN, "UE-REGISTER-REQ without IMSI?!?\n"); + return -1; + } - DEBUGP(DMAIN, "UE-REGSITER-REQ ID_type=%d cause=%ld\n", - ies.uE_Identity.present, ies.registration_Cause); + DEBUGP(DMAIN, "UE-REGSITER-REQ ID_type=%d imsi=%s cause=%ld\n", + ies.uE_Identity.present, imsi, ies.registration_Cause); + + ue = ue_context_by_imsi(imsi); + if (!ue) + ue = ue_context_alloc(ctx, imsi); /* Send UERegisterAccept */ return hnbgw_tx_ue_register_acc(ue);