aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/include/openbsc/gsm_subscriber.h
blob: 62d121365a177de5204771cd91d9ca2ffac35b32 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#ifndef _GSM_SUBSCR_H
#define _GSM_SUBSCR_H

#include <stdbool.h>

#include "gsm_data.h"
#include <osmocom/core/linuxlist.h>

#define GSM_IMEI_LENGTH 17
#define GSM_IMSI_LENGTH 17
#define GSM_NAME_LENGTH 160

#define GSM_EXTENSION_LENGTH 15 /* MSISDN can only be 15 digits length */
#define GSM_MIN_EXTEN 20000
#define GSM_MAX_EXTEN 49999

#define GSM_SUBSCRIBER_FIRST_CONTACT	0x00000001
/* gprs_sgsn.h defines additional flags including and above bit 16 (0x10000) */
#define tmsi_from_string(str) strtoul(str, NULL, 10)

#define GSM_SUBSCRIBER_NO_EXPIRATION	0x0

struct vty;
struct sgsn_mm_ctx;
struct sgsn_subscriber_data;

struct subscr_request;

struct gsm_subscriber_group {
	struct gsm_network *net;

	int keep_subscr;
};

struct gsm_equipment {
	long long unsigned int id;
	char imei[GSM_IMEI_LENGTH];
	char name[GSM_NAME_LENGTH];

	struct gsm48_classmark1 classmark1;
	uint8_t classmark2_len;
	uint8_t classmark2[3];
	uint8_t classmark3_len;
	uint8_t classmark3[14];
};

struct gsm_subscriber {
	struct gsm_subscriber_group *group;
	long long unsigned int id;
	char imsi[GSM_IMSI_LENGTH];
	uint32_t tmsi;
	uint16_t lac;
	char name[GSM_NAME_LENGTH];
	char extension[GSM_EXTENSION_LENGTH];
	int authorized;
	time_t expire_lu;

	/* Don't delete subscribers even if group->keep_subscr is not set */
	int keep_in_ram;

	/* Temporary field which is not stored in the DB/HLR */
	uint32_t flags;

	/* Every user can only have one equipment in use at any given
	 * point in time */
	struct gsm_equipment equipment;

	/* for internal management */
	int use_count;
	struct llist_head entry;

	/* pending requests */
	int is_paging;
	struct osmo_timer_list paging_timeout;
	struct llist_head requests;

	/* GPRS/SGSN related fields */
	struct sgsn_subscriber_data *sgsn_data;
};

enum gsm_subscriber_field {
	GSM_SUBSCRIBER_IMSI,
	GSM_SUBSCRIBER_TMSI,
	GSM_SUBSCRIBER_EXTENSION,
	GSM_SUBSCRIBER_ID,
};

enum gsm_subscriber_update_reason {
	GSM_SUBSCRIBER_UPDATE_ATTACHED,
	GSM_SUBSCRIBER_UPDATE_DETACHED,
	GSM_SUBSCRIBER_UPDATE_EQUIPMENT,
};

/*
 * Struct for pending channel requests. This is managed in the
 * llist_head requests of each subscriber. The reference counting
 * should work in such a way that a subscriber with a pending request
 * remains in memory.
 */
struct subscr_request {
	struct llist_head entry;

	/* the callback data */
	gsm_cbfn *cbfn;
	void *param;
};

struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr);
struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr);
struct gsm_subscriber *subscr_create_subscriber(struct gsm_subscriber_group *sgrp,
						const char *imsi);
struct gsm_subscriber *subscr_get_by_tmsi(struct gsm_subscriber_group *sgrp,
					  uint32_t tmsi);
struct gsm_subscriber *subscr_get_by_imsi(struct gsm_subscriber_group *sgrp,
					  const char *imsi);
struct gsm_subscriber *subscr_get_by_extension(struct gsm_subscriber_group *sgrp,
					       const char *ext);
struct gsm_subscriber *subscr_get_by_id(struct gsm_subscriber_group *sgrp,
					unsigned long long id);
struct gsm_subscriber *subscr_get_or_create(struct gsm_subscriber_group *sgrp,
					const char *imsi);
int subscr_update(struct gsm_network *network, struct gsm_subscriber *s,
		  uint16_t lac, int reason);
struct gsm_subscriber *subscr_active_by_tmsi(struct gsm_subscriber_group *sgrp,
					     uint32_t tmsi);
struct gsm_subscriber *subscr_active_by_imsi(struct gsm_subscriber_group *sgrp,
					     const char *imsi);

char *subscr_name(struct gsm_subscriber *subscr);

int subscr_purge_inactive(struct gsm_subscriber_group *sgrp);
void subscr_update_from_db(struct gsm_subscriber *subscr);
void subscr_expire(struct gsm_subscriber_group *sgrp);
int subscr_update_expire_lu(struct gsm_network *network, struct gsm_subscriber *subscr);

bool subscr_authorized(struct gsm_subscriber *subsc);

/*
 * Paging handling with authentication
 */
struct subscr_request *subscr_request_conn(struct gsm_subscriber *subscr,
					   gsm_cbfn *cbfn, void *param);
void subscr_remove_request(struct subscr_request *req);
int subscr_rx_paging_response(struct msgb *msg,
			      struct gsm_subscriber_connection *conn);

/* internal */
struct gsm_subscriber *subscr_alloc(void);
extern struct llist_head active_subscribers;

#endif /* _GSM_SUBSCR_H */