static void test_sms_migrate(void) { struct gsm_subscriber *rcv_subscr; struct gsm_sms *sms; static const uint8_t user_data_1[] = { 0x41, 0xf1, 0xd8, 0x05, 0x22, 0x96, 0xcd, 0x2e, 0x90, 0xf1, 0xfd, 0x06, 0x00 }; static const uint8_t user_data_2[] = { 0x41, 0xf1, 0xd8, 0x05, 0x22, 0x96, 0xcd, 0x2e, 0xd0, 0xf1, 0xfd, 0x06, 0x00 }; rcv_subscr = db_get_subscriber(GSM_SUBSCRIBER_IMSI, "901010000001111"); rcv_subscr->group = &dummy_sgrp; sms = db_sms_get(&dummy_net, 1); OSMO_ASSERT(sms->id == 1); OSMO_ASSERT(sms->receiver == rcv_subscr); OSMO_ASSERT(strcmp(sms->text, "Abc. Def. Foo") == 0); OSMO_ASSERT(sms->user_data_len == ARRAY_SIZE(user_data_1)); OSMO_ASSERT(memcmp(sms->user_data, user_data_1, ARRAY_SIZE(user_data_1)) == 0); sms_free(sms); sms = db_sms_get(&dummy_net, 2); OSMO_ASSERT(sms->id == 2); OSMO_ASSERT(sms->receiver == rcv_subscr); OSMO_ASSERT(strcmp(sms->text, "Abc. Def. Goo") == 0); OSMO_ASSERT(sms->user_data_len == ARRAY_SIZE(user_data_2)); OSMO_ASSERT(memcmp(sms->user_data, user_data_2, ARRAY_SIZE(user_data_2)) == 0); sms_free(sms); subscr_put(rcv_subscr); }
/* TODO: move subscriber put here... */ void subscr_con_free(struct gsm_subscriber_connection *conn) { if (!conn) return; if (conn->subscr) { subscr_put(conn->subscr); conn->subscr = NULL; } if (conn->ho_lchan) { LOGP(DNM, LOGL_ERROR, "The ho_lchan should have been cleared.\n"); conn->ho_lchan->conn = NULL; } if (conn->lchan) { LOGP(DNM, LOGL_ERROR, "The lchan should have been cleared.\n"); conn->lchan->conn = NULL; } if (conn->secondary_lchan) { LOGP(DNM, LOGL_ERROR, "The secondary_lchan should have been cleared.\n"); conn->secondary_lchan->conn = NULL; } llist_del(&conn->entry); talloc_free(conn); }
/* * We got the channel assigned and can now hand this channel * over to one of our callbacks. */ static int subscr_paging_cb(unsigned int hooknum, unsigned int event, struct msgb *msg, void *data, void *param) { struct subscr_request *request; struct gsm_subscriber *subscr = (struct gsm_subscriber *)param; /* There is no request anymore... */ if (llist_empty(&subscr->requests)) return -1; /* * FIXME: What to do with paging requests coming during * this callback? We must be sure to not start paging when * we have an active connection to a subscriber and to make * the subscr_put_channel work as required... */ request = (struct subscr_request *)subscr->requests.next; llist_del(&request->entry); subscr->in_callback = 1; request->cbfn(hooknum, event, msg, data, request->param); subscr->in_callback = 0; subscr_put(subscr); talloc_free(request); return 0; }
static int set_subscriber_delete(struct ctrl_cmd *cmd, void *data) { int was_used = 0; int rc; struct gsm_subscriber *subscr; struct gsm_network *net = cmd->node; subscr = subscr_get_by_imsi(net->subscr_group, cmd->value); if (!subscr) { cmd->reply = "Failed to find subscriber"; return CTRL_CMD_ERROR; } if (subscr->use_count != 1) { LOGP(DCTRL, LOGL_NOTICE, "Going to remove active subscriber.\n"); was_used = 1; } rc = db_subscriber_delete(subscr); subscr_put(subscr); if (rc != 0) { cmd->reply = "Failed to remove subscriber"; return CTRL_CMD_ERROR; } cmd->reply = was_used ? "Removed active subscriber" : "Removed"; return CTRL_CMD_REPLY; }
/* we will need to stop the paging request */ static int handle_page_resp(struct gsm_subscriber_connection *conn, struct msgb *msg) { uint8_t mi_type; char mi_string[GSM48_MI_SIZE]; struct gsm48_hdr *gh; struct gsm48_pag_resp *resp; struct gsm_subscriber *subscr; if (msgb_l3len(msg) < sizeof(*gh) + sizeof(*resp)) { LOGP(DMSC, LOGL_ERROR, "PagingResponse too small: %u\n", msgb_l3len(msg)); return -1; } gh = msgb_l3(msg); resp = (struct gsm48_pag_resp *) &gh->data[0]; gsm48_paging_extract_mi(resp, msgb_l3len(msg) - sizeof(*gh), mi_string, &mi_type); DEBUGP(DRR, "PAGING RESPONSE: mi_type=0x%02x MI(%s)\n", mi_type, mi_string); switch (mi_type) { case GSM_MI_TYPE_TMSI: subscr = subscr_active_by_tmsi(conn->bts->network, tmsi_from_string(mi_string)); break; case GSM_MI_TYPE_IMSI: subscr = subscr_active_by_imsi(conn->bts->network, mi_string); break; default: subscr = NULL; break; } if (!subscr) { LOGP(DMSC, LOGL_ERROR, "Non active subscriber got paged.\n"); return -1; } paging_request_stop(conn->bts, subscr, conn, msg); subscr_put(subscr); return 0; }
/* * Create/Store a SMS and then try to load it. */ static void test_sms(void) { int rc; struct gsm_sms *sms; struct gsm_subscriber *subscr; subscr = db_get_subscriber(GSM_SUBSCRIBER_IMSI, "9993245423445"); OSMO_ASSERT(subscr); subscr->group = &dummy_sgrp; sms = sms_alloc(); sms->receiver = subscr_get(subscr); sms->src.ton = 0x23; sms->src.npi = 0x24; memcpy(sms->src.addr, "1234", strlen("1234") + 1); sms->dst.ton = 0x32; sms->dst.npi = 0x42; memcpy(sms->dst.addr, subscr->extension, sizeof(subscr->extension)); memcpy(sms->text, "Text123", strlen("Text123") + 1); memcpy(sms->user_data, "UserData123", strlen("UserData123") + 1); sms->user_data_len = strlen("UserData123"); /* random values */ sms->reply_path_req = 1; sms->status_rep_req = 2; sms->ud_hdr_ind = 3; sms->protocol_id = 4; sms->data_coding_scheme = 5; rc = db_sms_store(sms); sms_free(sms); OSMO_ASSERT(rc == 0); /* now query */ sms = db_sms_get_unsent_for_subscr(subscr); OSMO_ASSERT(sms); OSMO_ASSERT(sms->receiver == subscr); OSMO_ASSERT(sms->reply_path_req == 1); OSMO_ASSERT(sms->status_rep_req == 2); OSMO_ASSERT(sms->ud_hdr_ind == 3); OSMO_ASSERT(sms->protocol_id == 4); OSMO_ASSERT(sms->data_coding_scheme == 5); OSMO_ASSERT(sms->src.ton == 0x23); OSMO_ASSERT(sms->src.npi == 0x24); OSMO_ASSERT(sms->dst.ton == 0x32); OSMO_ASSERT(sms->dst.npi == 0x42); OSMO_ASSERT(strcmp((char *) sms->text, "Text123") == 0); OSMO_ASSERT(sms->user_data_len == strlen("UserData123")); OSMO_ASSERT(strcmp((char *) sms->user_data, "UserData123") == 0); /* Mark the SMS as delivered */ db_sms_mark_delivered(sms); sms_free(sms); sms = db_sms_get_unsent_for_subscr(subscr); OSMO_ASSERT(!sms); subscr_put(subscr); }
static int set_subscriber_modify(struct ctrl_cmd *cmd, void *data) { struct gsm_network *net = cmd->node; char *tmp, *imsi, *msisdn, *alg, *ki, *saveptr = NULL; struct gsm_subscriber* subscr; int rc; tmp = talloc_strdup(cmd, cmd->value); if (!tmp) return 1; imsi = strtok_r(tmp, ",", &saveptr); msisdn = strtok_r(NULL, ",", &saveptr); alg = strtok_r(NULL, ",", &saveptr); ki = strtok_r(NULL, ",", &saveptr); subscr = subscr_get_by_imsi(net->subscr_group, imsi); if (!subscr) subscr = subscr_create_subscriber(net->subscr_group, imsi); if (!subscr) goto fail; subscr->authorized = 1; strncpy(subscr->extension, msisdn, GSM_EXTENSION_LENGTH - 1); subscr->extension[GSM_EXTENSION_LENGTH-1] = '\0'; /* put it back to the db */ rc = db_sync_subscriber(subscr); db_subscriber_update(subscr); /* handle optional ciphering */ if (alg) { if (strcasecmp(alg, "none") == 0) db_sync_authinfo_for_subscr(NULL, subscr); else { struct gsm_auth_info ainfo = { 0, }; /* the verify should make sure that this is okay */ OSMO_ASSERT(alg); OSMO_ASSERT(ki); if (strcasecmp(alg, "xor") == 0) ainfo.auth_algo = AUTH_ALGO_XOR; else if (strcasecmp(alg, "comp128v1") == 0) ainfo.auth_algo = AUTH_ALGO_COMP128v1; rc = osmo_hexparse(ki, ainfo.a3a8_ki, sizeof(ainfo.a3a8_ki)); if (rc < 0) { subscr_put(subscr); talloc_free(tmp); cmd->reply = "Failed to parse KI"; return CTRL_CMD_ERROR; } ainfo.a3a8_ki_len = rc; db_sync_authinfo_for_subscr(&ainfo, subscr); rc = 0; } db_sync_lastauthtuple_for_subscr(NULL, subscr); } subscr_put(subscr); talloc_free(tmp); if (rc != 0) { cmd->reply = "Failed to store the record in the DB"; return CTRL_CMD_ERROR; } cmd->reply = "OK"; return CTRL_CMD_REPLY; fail: talloc_free(tmp); cmd->reply = "Failed to create subscriber"; return CTRL_CMD_ERROR; }