From ee4410a4f312d927dc8b4901c71c52436c18ca4a Mon Sep 17 00:00:00 2001 From: "Harald Welte (local)" Date: Mon, 17 Aug 2009 09:39:55 +0200 Subject: [PATCH] actual code running at end of har2009 --- openbsc/src/bsc_hack.c | 13 ++++++++ openbsc/src/db.c | 69 ++++++++++++++++++++++++++++++++++++++--- openbsc/src/gsm_04_08.c | 9 +++++- openbsc/src/gsm_04_11.c | 8 +++++ 4 files changed, 94 insertions(+), 5 deletions(-) diff --git a/openbsc/src/bsc_hack.c b/openbsc/src/bsc_hack.c index 47f53cd07..9945aa9c9 100644 --- a/openbsc/src/bsc_hack.c +++ b/openbsc/src/bsc_hack.c @@ -930,6 +930,8 @@ static void patch_si_tables(struct gsm_bts *bts) (struct gsm48_system_information_type_3*)&si3; struct gsm48_system_information_type_4 *type_4 = (struct gsm48_system_information_type_4*)&si4; + struct gsm48_system_information_type_5 *type_5 = + (struct gsm48_system_information_type_5*)&si5; struct gsm48_system_information_type_6 *type_6 = (struct gsm48_system_information_type_6*)&si6; struct gsm48_loc_area_id lai; @@ -969,6 +971,17 @@ static void patch_si_tables(struct gsm_bts *bts) type_3->rach_control.cell_bar = 0; type_4->rach_control.cell_bar = 0; } + + /* FIXME: This is just for HAR */ + if (bts->c0->arfcn == 121) { + /* this is setting pin 124 */ + type_2->bcch_frequency_list[0] = 0x08; + type_5->bcch_frequency_list[0] = 0x08; + } else if (bts->c0->arfcn == 124) { + /* this is setting pin 121 */ + type_2->bcch_frequency_list[0] = 0x01; + type_5->bcch_frequency_list[0] = 0x01; + } } diff --git a/openbsc/src/db.c b/openbsc/src/db.c index 16a7f6ad7..45e950b6f 100644 --- a/openbsc/src/db.c +++ b/openbsc/src/db.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -260,6 +261,53 @@ struct gsm_subscriber* db_create_subscriber(struct gsm_network *net, char *imsi) return subscr; } +static int get_equipment_by_subscr(struct gsm_subscriber *subscr) +{ + dbi_result result; + char *string; + unsigned int cm1; + const unsigned char *cm2, *cm3; + struct gsm_equipment *equip = &subscr->equipment; + + result = dbi_conn_queryf(conn, + "SELECT equipment.* FROM equipment,equipmentwatch " + "WHERE equipmentwatch.equipment_id=equipment.id " + "AND equipmentwatch.subscriber_id = %llu " + "ORDER BY updated DESC", subscr->id); + if (!result) + return -EIO; + + if (!dbi_result_next_row(result)) { + dbi_result_free(result); + return -ENOENT; + } + + equip->id = dbi_result_get_ulonglong(result, "id"); + + string = dbi_result_get_string(result, "imei"); + if (string) + strncpy(equip->imei, string, sizeof(equip->imei)); + + cm1 = dbi_result_get_uint(result, "classmark1") & 0xff; + equip->classmark1 = *((struct gsm48_classmark1 *) &cm1); + + equip->classmark2_len = dbi_result_get_field_length(result, "classmark2"); + cm2 = dbi_result_get_binary(result, "classmark2"); + if (equip->classmark2_len > sizeof(equip->classmark2)) + equip->classmark2_len = sizeof(equip->classmark2); + memcpy(equip->classmark2, cm2, equip->classmark2_len); + + equip->classmark3_len = dbi_result_get_field_length(result, "classmark3"); + cm3 = dbi_result_get_binary(result, "classmark3"); + if (equip->classmark3_len > sizeof(equip->classmark3)) + equip->classmark3_len = sizeof(equip->classmark3); + memcpy(equip->classmark3, cm3, equip->classmark3_len); + + dbi_result_free(result); + + return 0; +} +#define BASE_QUERY "SELECT * FROM Subscriber " struct gsm_subscriber *db_get_subscriber(struct gsm_network *net, enum gsm_subscriber_field field, const char *id) @@ -273,7 +321,7 @@ struct gsm_subscriber *db_get_subscriber(struct gsm_network *net, case GSM_SUBSCRIBER_IMSI: dbi_conn_quote_string_copy(conn, id, "ed); result = dbi_conn_queryf(conn, - "SELECT * FROM Subscriber " + BASE_QUERY "WHERE imsi = %s ", quoted ); @@ -282,7 +330,7 @@ struct gsm_subscriber *db_get_subscriber(struct gsm_network *net, case GSM_SUBSCRIBER_TMSI: dbi_conn_quote_string_copy(conn, id, "ed); result = dbi_conn_queryf(conn, - "SELECT * FROM Subscriber " + BASE_QUERY "WHERE tmsi = %s ", quoted ); @@ -291,7 +339,7 @@ struct gsm_subscriber *db_get_subscriber(struct gsm_network *net, case GSM_SUBSCRIBER_EXTENSION: dbi_conn_quote_string_copy(conn, id, "ed); result = dbi_conn_queryf(conn, - "SELECT * FROM Subscriber " + BASE_QUERY "WHERE extension = %s ", quoted ); @@ -300,7 +348,7 @@ struct gsm_subscriber *db_get_subscriber(struct gsm_network *net, case GSM_SUBSCRIBER_ID: dbi_conn_quote_string_copy(conn, id, "ed); result = dbi_conn_queryf(conn, - "SELECT * FROM Subscriber " + BASE_QUERY "WHERE id = %s ", quoted); free(quoted); break; @@ -344,6 +392,9 @@ struct gsm_subscriber *db_get_subscriber(struct gsm_network *net, subscr->id, subscr->imsi, subscr->name, subscr->tmsi, subscr->extension, subscr->lac, subscr->authorized); dbi_result_free(result); + + get_equipment_by_subscr(subscr); + return subscr; } @@ -386,6 +437,16 @@ int db_sync_equipment(struct gsm_equipment *equip) dbi_result result; unsigned char *cm2, *cm3; + printf("DB: Sync Equipment IMEI=%s, classmark1=%02x", + equip->imei, equip->classmark1); + if (equip->classmark2_len) + printf(", classmark2=%s", + hexdump(equip->classmark2, equip->classmark2_len)); + if (equip->classmark3_len) + printf(", classmark3=%s", + hexdump(equip->classmark3, equip->classmark3_len)); + printf("\n"); + dbi_conn_quote_binary_copy(conn, equip->classmark2, equip->classmark2_len, &cm2); dbi_conn_quote_binary_copy(conn, equip->classmark3, diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index b64d2536a..46b447900 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -1165,8 +1165,10 @@ static int mm_rx_id_resp(struct msgb *msg) case GSM_MI_TYPE_IMEI: case GSM_MI_TYPE_IMEISV: /* update subscribe <-> IMEI mapping */ - if (lchan->subscr) + if (lchan->subscr) { db_subscriber_assoc_imei(lchan->subscr, mi_string); + db_sync_equipment(&lchan->subscr->equipment); + } if (lchan->loc_operation) lchan->loc_operation->waiting_for_imei = 0; break; @@ -1289,6 +1291,7 @@ static int mm_rx_loc_upd_req(struct msgb *msg) } lchan->subscr = subscr; + lchan->subscr->equipment.classmark1 = lu->classmark1; /* check if we can let the subscriber into our network immediately * or if we need to wait for identity responses. */ @@ -1614,6 +1617,10 @@ static int gsm48_rx_mm_imsi_detach_ind(struct msgb *msg) GSM_SUBSCRIBER_UPDATE_DETACHED); DEBUGP(DMM, "Subscriber: %s\n", subscr->name ? subscr->name : subscr->imsi); + + subscr->equipment.classmark1 = idi->classmark1; + db_sync_equipment(&subscr->equipment); + subscr_put(subscr); } else DEBUGP(DMM, "Unknown Subscriber ?!?\n"); diff --git a/openbsc/src/gsm_04_11.c b/openbsc/src/gsm_04_11.c index 277a321a8..85fd6b690 100644 --- a/openbsc/src/gsm_04_11.c +++ b/openbsc/src/gsm_04_11.c @@ -295,6 +295,9 @@ static int gsm340_rx_sms_submit(struct msgb *msg, struct gsm_sms *gsms) } /* dispatch a signal to tell higher level about it */ dispatch_signal(SS_SMS, S_SMS_SUBMITTED, gsms); + /* try delivering the SMS right now */ + //gsm411_send_sms_subscr(gsms->receiver, gsms); + return 0; } @@ -675,14 +678,19 @@ static int gsm411_rx_rp_error(struct msgb *msg, struct gsm_trans *trans, if (!trans->sms.is_mt) { DEBUGP(DSMS, "RX RP-ERR on a MO transfer ?\n"); +#if 0 return gsm411_send_rp_error(trans, rph->msg_ref, GSM411_RP_CAUSE_MSG_INCOMP_STATE); +#endif } if (!sms) { DEBUGP(DSMS, "RX RP-ERR, but no sms in transaction?!?\n"); + return -EINVAL; +#if 0 return gsm411_send_rp_error(trans, rph->msg_ref, GSM411_RP_CAUSE_PROTOCOL_ERR); +#endif } if (cause == GSM411_RP_CAUSE_MT_MEM_EXCEEDED) {