diff options
-rw-r--r-- | openbsc/include/openbsc/db.h | 1 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_subscriber.h | 9 | ||||
-rw-r--r-- | openbsc/src/libbsc/bsc_vty.c | 3 | ||||
-rw-r--r-- | openbsc/src/libmsc/db.c | 33 | ||||
-rw-r--r-- | openbsc/src/libmsc/gsm_subscriber.c | 3 | ||||
-rw-r--r-- | openbsc/src/libmsc/sip_sms.c | 1 | ||||
-rw-r--r-- | openbsc/src/libmsc/smpp_openbsc.c | 2 | ||||
-rw-r--r-- | openbsc/src/libmsc/vty_interface_layer3.c | 3 | ||||
-rw-r--r-- | openbsc/tests/db/db_test.c | 109 |
9 files changed, 131 insertions, 33 deletions
diff --git a/openbsc/include/openbsc/db.h b/openbsc/include/openbsc/db.h index 25c2aea70..e015a18ae 100644 --- a/openbsc/include/openbsc/db.h +++ b/openbsc/include/openbsc/db.h @@ -44,6 +44,7 @@ int db_sync_subscriber(struct gsm_subscriber *subscriber); int db_subscriber_expire(void *priv, void (*callback)(void *priv, long long unsigned int id)); int db_subscriber_alloc_tmsi(struct gsm_subscriber *subscriber); int db_subscriber_alloc_exten(struct gsm_subscriber *subscriber); +int db_subscriber_assoc_extern_number(struct gsm_subscriber *subscriber, char *extern_number); int db_subscriber_alloc_token(struct gsm_subscriber *subscriber, uint32_t* token); int db_subscriber_assoc_imei(struct gsm_subscriber *subscriber, char *imei); int db_sync_equipment(struct gsm_equipment *equip); diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h index 1b74256cd..58b280bdd 100644 --- a/openbsc/include/openbsc/gsm_subscriber.h +++ b/openbsc/include/openbsc/gsm_subscriber.h @@ -43,6 +43,15 @@ struct gsm_subscriber { uint16_t lac; char name[GSM_NAME_LENGTH]; char extension[GSM_EXTENSION_LENGTH]; + /* Optional: an external phone number alias. + * + * This allows user to have an internal short number, while having an + * external globally routable MSISDN at the same time. + * If external_number is set for a user, it will be used for all + * communications outside our network instead of the internal extension. + * + * PS At this moment it is used only by incoming/outgoing SMPP SMS. */ + char external_number[GSM_EXTENSION_LENGTH+1]; int authorized; time_t expire_lu; diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index e41d4de4c..90c7e3464 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -964,6 +964,9 @@ static void subscr_dump_vty(struct vty *vty, struct gsm_subscriber *subscr) if (subscr->extension) vty_out(vty, " Extension: %s%s", subscr->extension, VTY_NEWLINE); + if (strlen(subscr->external_number)) + vty_out(vty, " External number: %s%s", subscr->external_number, + VTY_NEWLINE); vty_out(vty, " IMSI: %s%s", subscr->imsi, VTY_NEWLINE); if (subscr->tmsi != GSM_RESERVED_TMSI) vty_out(vty, " TMSI: %08X%s", subscr->tmsi, diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c index 9a8cd886b..d71a6b142 100644 --- a/openbsc/src/libmsc/db.c +++ b/openbsc/src/libmsc/db.c @@ -61,6 +61,7 @@ static char *create_stmts[] = { "imsi NUMERIC UNIQUE NOT NULL, " "name TEXT, " "extension TEXT UNIQUE, " + "external_number TEXT, " "authorized INTEGER NOT NULL DEFAULT 0, " "tmsi TEXT UNIQUE, " "lac INTEGER NOT NULL DEFAULT 0, " @@ -634,6 +635,10 @@ static void db_set_from_query(struct gsm_subscriber *subscr, dbi_conn result) if (string) strncpy(subscr->extension, string, GSM_EXTENSION_LENGTH); + string = dbi_result_get_string(result, "external_number"); + if (string) + strncpy(subscr->external_number, string, GSM_EXTENSION_LENGTH); + subscr->lac = dbi_result_get_uint(result, "lac"); if (!dbi_result_field_is_null(result, "expire_lu")) @@ -676,8 +681,8 @@ struct gsm_subscriber *db_get_subscriber(struct gsm_network *net, dbi_conn_quote_string_copy(conn, id, "ed); result = dbi_conn_queryf(conn, BASE_QUERY - "WHERE extension = %s ", - quoted + "WHERE extension = %s OR external_number = %s ", + quoted, quoted ); free(quoted); break; @@ -708,8 +713,9 @@ struct gsm_subscriber *db_get_subscriber(struct gsm_network *net, subscr->id = dbi_result_get_ulonglong(result, "id"); db_set_from_query(subscr, result); - DEBUGP(DDB, "Found Subscriber: ID %llu, IMSI %s, NAME '%s', TMSI %u, EXTEN '%s', LAC %hu, AUTH %u\n", - subscr->id, subscr->imsi, subscr->name, subscr->tmsi, subscr->extension, + DEBUGP(DDB, "Found Subscriber: ID %llu, IMSI %s, NAME '%s', TMSI %u, EXTEN '%s', EXTERN '%s', LAC %hu, AUTH %u\n", + subscr->id, subscr->imsi, subscr->name, subscr->tmsi, + subscr->extension, subscr->external_number, subscr->lac, subscr->authorized); dbi_result_free(result); @@ -751,12 +757,14 @@ int db_sync_subscriber(struct gsm_subscriber *subscriber) { dbi_result result; char tmsi[14]; - char *q_tmsi, *q_name, *q_extension; + char *q_tmsi, *q_name, *q_extension, *q_external_number; dbi_conn_quote_string_copy(conn, subscriber->name, &q_name); dbi_conn_quote_string_copy(conn, subscriber->extension, &q_extension); + dbi_conn_quote_string_copy(conn, + subscriber->external_number, &q_external_number); if (subscriber->tmsi != GSM_RESERVED_TMSI) { sprintf(tmsi, "%u", subscriber->tmsi); @@ -772,6 +780,7 @@ int db_sync_subscriber(struct gsm_subscriber *subscriber) "SET updated = datetime('now'), " "name = %s, " "extension = %s, " + "external_number = %s, " "authorized = %i, " "tmsi = %s, " "lac = %i, " @@ -779,6 +788,7 @@ int db_sync_subscriber(struct gsm_subscriber *subscriber) "WHERE imsi = %s ", q_name, q_extension, + q_external_number, subscriber->authorized, q_tmsi, subscriber->lac, @@ -789,6 +799,7 @@ int db_sync_subscriber(struct gsm_subscriber *subscriber) "SET updated = datetime('now'), " "name = %s, " "extension = %s, " + "external_number = %s, " "authorized = %i, " "tmsi = %s, " "lac = %i, " @@ -796,6 +807,7 @@ int db_sync_subscriber(struct gsm_subscriber *subscriber) "WHERE imsi = %s ", q_name, q_extension, + q_external_number, subscriber->authorized, q_tmsi, subscriber->lac, @@ -806,6 +818,7 @@ int db_sync_subscriber(struct gsm_subscriber *subscriber) free(q_tmsi); free(q_name); free(q_extension); + free(q_external_number); if (!result) { LOGP(DDB, LOGL_ERROR, "Failed to update Subscriber (by IMSI).\n"); @@ -957,6 +970,16 @@ int db_subscriber_alloc_exten(struct gsm_subscriber *subscriber) DEBUGP(DDB, "Allocated extension %i for IMSI %s.\n", try, subscriber->imsi); return db_sync_subscriber(subscriber); } + +int db_subscriber_assoc_extern_number(struct gsm_subscriber *subscriber, char *extern_number) +{ + strncpy(subscriber->external_number, extern_number, + sizeof(subscriber->external_number)-1); + DEBUGP(DDB, "Associated external number '%s' for "GSM_SUBS_FMT_STR".\n", + subscriber->external_number, GSM_SUBS_FMT_VAL(subscriber)); + return db_sync_subscriber(subscriber); +} + /* * try to allocate a new unique token for this subscriber and return it * via a parameter. if the subscriber already has a token, return diff --git a/openbsc/src/libmsc/gsm_subscriber.c b/openbsc/src/libmsc/gsm_subscriber.c index 5ace8f666..594a72b3a 100644 --- a/openbsc/src/libmsc/gsm_subscriber.c +++ b/openbsc/src/libmsc/gsm_subscriber.c @@ -302,7 +302,8 @@ struct gsm_subscriber *subscr_get_by_extension(struct gsm_network *net, struct gsm_subscriber *subscr; llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) { - if (strcmp(subscr->extension, ext) == 0) + if (strcmp(subscr->extension, ext) == 0 + || strcmp(subscr->external_number, ext) == 0) return subscr_get(subscr); } diff --git a/openbsc/src/libmsc/sip_sms.c b/openbsc/src/libmsc/sip_sms.c new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/openbsc/src/libmsc/sip_sms.c @@ -0,0 +1 @@ + diff --git a/openbsc/src/libmsc/smpp_openbsc.c b/openbsc/src/libmsc/smpp_openbsc.c index 8e0085d0c..dc6bf8d91 100644 --- a/openbsc/src/libmsc/smpp_openbsc.c +++ b/openbsc/src/libmsc/smpp_openbsc.c @@ -446,7 +446,7 @@ static int deliver_to_esme(struct osmo_esme *esme, struct gsm_sms *sms, deliver.source_addr_npi = NPI_ISDN_E163_E164; snprintf((char *)deliver.source_addr, sizeof(deliver.source_addr), "%s", - sms->sender->extension); + strlen(sms->sender->external_number)?sms->sender->external_number:sms->sender->extension); } deliver.dest_addr_ton = sms->dst.ton; diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index 5ef449790..4daa3c6c5 100644 --- a/openbsc/src/libmsc/vty_interface_layer3.c +++ b/openbsc/src/libmsc/vty_interface_layer3.c @@ -65,6 +65,9 @@ static void subscr_dump_full_vty(struct vty *vty, struct gsm_subscriber *subscr, if (subscr->extension) vty_out(vty, " Extension: %s%s", subscr->extension, VTY_NEWLINE); + if (strlen(subscr->external_number)) + vty_out(vty, " External number: %s%s", subscr->external_number, + VTY_NEWLINE); vty_out(vty, " LAC: %d/0x%x%s", subscr->lac, subscr->lac, VTY_NEWLINE); vty_out(vty, " IMSI: %s%s", subscr->imsi, VTY_NEWLINE); diff --git a/openbsc/tests/db/db_test.c b/openbsc/tests/db/db_test.c index c3beee22f..7cf656196 100644 --- a/openbsc/tests/db/db_test.c +++ b/openbsc/tests/db/db_test.c @@ -26,39 +26,55 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <inttypes.h> static struct gsm_network dummy_net; #define SUBSCR_PUT(sub) \ - sub->net = &dummy_net; \ - subscr_put(sub); + if (sub) { \ + sub->net = &dummy_net; \ + subscr_put(sub); \ + } #define COMPARE(original, copy) \ - if (original->id != copy->id) \ - printf("Ids do not match in %s:%d %llu %llu\n", \ - __FUNCTION__, __LINE__, original->id, copy->id); \ - if (original->lac != copy->lac) \ - printf("LAC do not match in %s:%d %d %d\n", \ - __FUNCTION__, __LINE__, original->lac, copy->lac); \ - if (original->authorized != copy->authorized) \ - printf("Authorize do not match in %s:%d %d %d\n", \ - __FUNCTION__, __LINE__, original->authorized, \ - copy->authorized); \ - if (strcmp(original->imsi, copy->imsi) != 0) \ - printf("IMSIs do not match in %s:%d '%s' '%s'\n", \ - __FUNCTION__, __LINE__, original->imsi, copy->imsi); \ - if (original->tmsi != copy->tmsi) \ - printf("TMSIs do not match in %s:%d '%u' '%u'\n", \ - __FUNCTION__, __LINE__, original->tmsi, copy->tmsi); \ - if (strcmp(original->name, copy->name) != 0) \ - printf("names do not match in %s:%d '%s' '%s'\n", \ - __FUNCTION__, __LINE__, original->name, copy->name); \ - if (strcmp(original->extension, copy->extension) != 0) \ - printf("Extensions do not match in %s:%d '%s' '%s'\n", \ - __FUNCTION__, __LINE__, original->extension, copy->extension); \ + if (!original) \ + printf("NULL original in %s:%d\n", \ + __FUNCTION__, __LINE__); \ + if (!copy) \ + printf("NULL copy in %s:%d\n", \ + __FUNCTION__, __LINE__); \ + if (original && copy) { \ + if (original->id != copy->id) \ + printf("Ids do not match in %s:%d %llu %llu\n", \ + __FUNCTION__, __LINE__, original->id, copy->id); \ + if (original->lac != copy->lac) \ + printf("LAC do not match in %s:%d %d %d\n", \ + __FUNCTION__, __LINE__, original->lac, copy->lac); \ + if (original->authorized != copy->authorized) \ + printf("Authorize do not match in %s:%d %d %d\n", \ + __FUNCTION__, __LINE__, original->authorized, \ + copy->authorized); \ + if (strcmp(original->imsi, copy->imsi) != 0) \ + printf("IMSIs do not match in %s:%d '%s' '%s'\n", \ + __FUNCTION__, __LINE__, original->imsi, copy->imsi); \ + if (original->tmsi != copy->tmsi) \ + printf("TMSIs do not match in %s:%d '%u' '%u'\n", \ + __FUNCTION__, __LINE__, original->tmsi, copy->tmsi); \ + if (strcmp(original->name, copy->name) != 0) \ + printf("names do not match in %s:%d '%s' '%s'\n", \ + __FUNCTION__, __LINE__, original->name, copy->name); \ + if (strcmp(original->extension, copy->extension) != 0) \ + printf("Extensions do not match in %s:%d '%s' '%s'\n", \ + __FUNCTION__, __LINE__, original->extension, copy->extension); \ + if (strcmp(original->external_number, copy->external_number) != 0) \ + printf("External numbers do not match in %s:%d '%s' '%s'\n", \ + __FUNCTION__, __LINE__, original->external_number, copy->external_number); \ + } int main() { + char scratch_str[256]; + printf("Testing subscriber database code.\n"); osmo_init_logging(&log_info); @@ -89,12 +105,32 @@ int main() alice = db_create_subscriber(NULL, alice_imsi); db_subscriber_assoc_imei(alice, "1234567890"); db_subscriber_alloc_tmsi(alice); + db_subscriber_assoc_extern_number(alice, "123456789012345"); alice->lac=42; db_sync_subscriber(alice); + /* Get by TMSI */ + snprintf(scratch_str, sizeof(scratch_str), "%"PRIu32, alice->tmsi); + alice_db = db_get_subscriber(NULL, GSM_SUBSCRIBER_TMSI, scratch_str); + COMPARE(alice, alice_db); + SUBSCR_PUT(alice_db); + /* Get by IMSI */ alice_db = db_get_subscriber(NULL, GSM_SUBSCRIBER_IMSI, alice_imsi); COMPARE(alice, alice_db); - SUBSCR_PUT(alice); SUBSCR_PUT(alice_db); + /* Get by id */ + snprintf(scratch_str, sizeof(scratch_str), "%llu", alice->id); + alice_db = db_get_subscriber(NULL, GSM_SUBSCRIBER_ID, scratch_str); + COMPARE(alice, alice_db); + SUBSCR_PUT(alice_db); + /* Get by extension */ + alice_db = db_get_subscriber(NULL, GSM_SUBSCRIBER_EXTENSION, alice->extension); + COMPARE(alice, alice_db); + SUBSCR_PUT(alice_db); + /* And now by the external number alias */ + alice_db = db_get_subscriber(NULL, GSM_SUBSCRIBER_EXTENSION, "123456789012345"); + COMPARE(alice, alice_db); + SUBSCR_PUT(alice_db); + SUBSCR_PUT(alice); alice_imsi = "9993245423445"; alice = db_create_subscriber(NULL, alice_imsi); @@ -103,10 +139,31 @@ int main() db_sync_subscriber(alice); db_subscriber_assoc_imei(alice, "1234567890"); db_subscriber_assoc_imei(alice, "6543560920"); + /* This number is too long and should be truncated. */ + db_subscriber_assoc_extern_number(alice, "2345678901234567890"); + /* Get by TMSI */ + snprintf(scratch_str, sizeof(scratch_str), "%"PRIu32, alice->tmsi); + alice_db = db_get_subscriber(NULL, GSM_SUBSCRIBER_TMSI, scratch_str); + COMPARE(alice, alice_db); + SUBSCR_PUT(alice_db); + /* Get by IMSI */ alice_db = db_get_subscriber(NULL, GSM_SUBSCRIBER_IMSI, alice_imsi); COMPARE(alice, alice_db); - SUBSCR_PUT(alice); SUBSCR_PUT(alice_db); + /* Get by id */ + snprintf(scratch_str, sizeof(scratch_str), "%llu", alice->id); + alice_db = db_get_subscriber(NULL, GSM_SUBSCRIBER_ID, scratch_str); + COMPARE(alice, alice_db); + SUBSCR_PUT(alice_db); + /* Get by extension */ + alice_db = db_get_subscriber(NULL, GSM_SUBSCRIBER_EXTENSION, alice->extension); + COMPARE(alice, alice_db); + SUBSCR_PUT(alice_db); + /* And now by the external number alias */ + alice_db = db_get_subscriber(NULL, GSM_SUBSCRIBER_EXTENSION, "234567890123456"); + COMPARE(alice, alice_db); + SUBSCR_PUT(alice_db); + SUBSCR_PUT(alice); db_fini(); |