blob: 4ee00b3ea4929ba4317910db00c1f8569f7be16d [file] [log] [blame]
Jan Luebbefaaa49c2008-12-27 01:07:07 +00001/* (C) 2008 by Jan Luebbe <jluebbe@debian.org>
2 * All Rights Reserved
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 */
19
20#include <openbsc/db.h>
Jan Luebbe7398eb92008-12-27 00:45:41 +000021
22#include <stdio.h>
Jan Luebbe5c15c852008-12-27 15:59:25 +000023#include <stdlib.h>
24#include <string.h>
Jan Luebbe7398eb92008-12-27 00:45:41 +000025#include <dbi/dbi.h>
26
27dbi_conn conn;
28
29void db__error_func(dbi_conn conn, void* data) {
Jan Luebbe5c15c852008-12-27 15:59:25 +000030 const char* msg;
31 dbi_conn_error(conn, &msg);
32 printf("DBI: %s\n", msg);
Jan Luebbe7398eb92008-12-27 00:45:41 +000033}
34
35int db_init() {
Jan Luebbe5c15c852008-12-27 15:59:25 +000036 dbi_initialize(NULL);
37 conn = dbi_conn_new("sqlite3");
38 if (conn==NULL) {
39 printf("DB: Failed to create connection.\n");
40 return 1;
41 }
Jan Luebbe7398eb92008-12-27 00:45:41 +000042
Jan Luebbe5c15c852008-12-27 15:59:25 +000043 dbi_conn_error_handler( conn, db__error_func, NULL );
Jan Luebbe7398eb92008-12-27 00:45:41 +000044
Jan Luebbe5c15c852008-12-27 15:59:25 +000045 /* MySQL
46 dbi_conn_set_option(conn, "host", "localhost");
47 dbi_conn_set_option(conn, "username", "your_name");
48 dbi_conn_set_option(conn, "password", "your_password");
49 dbi_conn_set_option(conn, "dbname", "your_dbname");
50 dbi_conn_set_option(conn, "encoding", "UTF-8");
51 */
Jan Luebbe7398eb92008-12-27 00:45:41 +000052
Jan Luebbe5c15c852008-12-27 15:59:25 +000053 /* SqLite 3 */
54 dbi_conn_set_option(conn, "sqlite3_dbdir", "/tmp");
55 dbi_conn_set_option(conn, "dbname", "hlr.sqlite3");
Jan Luebbe7398eb92008-12-27 00:45:41 +000056
Jan Luebbe5c15c852008-12-27 15:59:25 +000057 if (dbi_conn_connect(conn) < 0) {
58 return 1;
59 }
60
61 return 0;
Jan Luebbe7398eb92008-12-27 00:45:41 +000062}
63
64int db_prepare() {
Jan Luebbe5c15c852008-12-27 15:59:25 +000065 dbi_result result;
66 result = dbi_conn_query(conn,
67 "CREATE TABLE IF NOT EXISTS Subscriber ("
68 "id INTEGER PRIMARY KEY AUTOINCREMENT, "
69 "imsi NUMERIC UNIQUE NOT NULL, "
70 "tmsi NUMERIC UNIQUE, "
71 "extension TEXT UNIQUE, "
72 "lac INTEGER"
73 ")"
74 );
75 if (result==NULL) {
76 printf("DB: Failed to create Subscriber table.\n");
77 return 1;
78 }
79 dbi_result_free(result);
80 result = dbi_conn_query(conn,
81 "CREATE TABLE IF NOT EXISTS Equipment ("
82 "id INTEGER PRIMARY KEY AUTOINCREMENT, "
83 "imei NUMERIC UNIQUE NOT NULL"
84 ")"
85 );
86 if (result==NULL) {
87 printf("DB: Failed to create Equipment table.\n");
88 return 1;
89 }
90 dbi_result_free(result);
91 return 0;
Jan Luebbe7398eb92008-12-27 00:45:41 +000092}
93
94int db_fini() {
Jan Luebbe5c15c852008-12-27 15:59:25 +000095 dbi_conn_close(conn);
96 dbi_shutdown();
97 return 0;
Jan Luebbe7398eb92008-12-27 00:45:41 +000098}
99
Jan Luebbe5c15c852008-12-27 15:59:25 +0000100int db_insert_imei(u_int64_t imei) {
101 dbi_result result;
102 result = dbi_conn_queryf(conn,
103 "INSERT OR IGNORE INTO Equipment "
104 "(imei) "
105 "VALUES "
106 "(%llu) ",
107 imei
108 );
109 if (result==NULL) {
110 printf("DB: Failed to create Equipment by IMEI.\n");
111 return 1;
112 }
113 dbi_result_free(result);
114 return 0;
Jan Luebbe7398eb92008-12-27 00:45:41 +0000115}
116
Jan Luebbe5c15c852008-12-27 15:59:25 +0000117struct gsm_subscriber* db_create_subscriber(char imsi[GSM_IMSI_LENGTH]) {
118 dbi_result result;
119 struct gsm_subscriber* subscriber;
120 subscriber = malloc(sizeof(*subscriber));
121 if (!subscriber)
122 return NULL;
123 memset(subscriber, 0, sizeof(*subscriber));
124 strncpy(subscriber->imsi, imsi, GSM_IMSI_LENGTH-1);
125 if (!db_get_subscriber(GSM_SUBSCRIBER_IMSI, subscriber)) {
126 return subscriber;
127 }
128 result = dbi_conn_queryf(conn,
129 "INSERT OR IGNORE INTO Subscriber "
130 "(imsi) "
131 "VALUES "
132 "(%s) ",
133 imsi
134 );
135 if (result==NULL) {
136 printf("DB: Failed to create Subscriber by IMSI.\n");
137 }
138 dbi_result_free(result);
139 printf("DB: New Subscriber: IMSI %s\n", subscriber->imsi);
140 return subscriber;
Jan Luebbe7398eb92008-12-27 00:45:41 +0000141}
142
Jan Luebbe5c15c852008-12-27 15:59:25 +0000143int db__parse_subscriber(dbi_result result, struct gsm_subscriber* subscriber) {
144 return 0;
Jan Luebbe7398eb92008-12-27 00:45:41 +0000145}
146
Jan Luebbe5c15c852008-12-27 15:59:25 +0000147int db_get_subscriber(enum gsm_subscriber_field field, struct gsm_subscriber* subscriber) {
148 dbi_result result;
149 switch (field) {
150 case GSM_SUBSCRIBER_IMSI:
151 result = dbi_conn_queryf(conn,
152 "SELECT * FROM Subscriber "
153 "WHERE imsi = %s ",
154 subscriber->imsi
155 );
156 break;
157 case GSM_SUBSCRIBER_TMSI:
158 result = dbi_conn_queryf(conn,
159 "SELECT * FROM Subscriber "
160 "WHERE tmsi = %s ",
161 subscriber->tmsi
162 );
163 break;
164 default:
165 printf("DB: Unknown query selector for Subscriber.\n");
166 return 1;
167 }
168 if (result==NULL) {
169 printf("DB: Failed to query Subscriber.\n");
170 return 1;
171 }
172 if (!dbi_result_next_row(result)) {
173 printf("DB: Failed to find the Subscriber.\n");
174 dbi_result_free(result);
175 return 1;
176 }
177 strncpy(subscriber->imsi, dbi_result_get_string(result, "imsi"), GSM_IMSI_LENGTH);
178 strncpy(subscriber->tmsi, dbi_result_get_string(result, "tmsi"), GSM_TMSI_LENGTH);
179 // FIXME handle extension
180 subscriber->lac = dbi_result_get_uint(result, "lac");
181 printf("DB: Found Subscriber: IMSI %s, TMSI %s, LAC %hu\n", subscriber->imsi, subscriber->tmsi, subscriber->lac);
182 dbi_result_free(result);
183 return 0;
Jan Luebbe7398eb92008-12-27 00:45:41 +0000184}
185
Jan Luebbe5c15c852008-12-27 15:59:25 +0000186int db_set_subscriber(struct gsm_subscriber* subscriber) {
187 dbi_result result;
188 result = dbi_conn_queryf(conn,
189 "UPDATE Subscriber "
190 "SET tmsi = %s, lac = %i "
191 "WHERE imsi = %s ",
192 subscriber->tmsi, subscriber->lac, subscriber->imsi
193 );
194 if (result==NULL) {
195 printf("DB: Failed to update Subscriber (by IMSI).\n");
196 return 1;
197 }
198 dbi_result_free(result);
199 return 0;
Jan Luebbe7398eb92008-12-27 00:45:41 +0000200}
201
Jan Luebbe5c15c852008-12-27 15:59:25 +0000202int db_subscriber_alloc_tmsi(struct gsm_subscriber* subscriber) {
203 int error;
204 dbi_result result=NULL;
205 char* tmsi_quoted;
206 for (;;) {
207 sprintf(subscriber->tmsi, "%i", rand() % 1000000); // FIXME how many nibbles do we want for the tmsi?
208 result = dbi_conn_queryf(conn,
209 "SELECT * FROM Subscriber "
210 "WHERE tmsi = %s ",
211 subscriber->tmsi
212 );
213 if (result==NULL) {
214 printf("DB: Failed to query Subscriber.\n");
215 return 1;
216 }
217 printf("%s\n", subscriber->tmsi);
218 printf("count %llu\n", dbi_result_get_numrows(result));
219 printf("curr %llu\n", dbi_result_get_currow(result));
220 printf("next %llu\n", dbi_result_next_row(result));
221 printf("count %llu\n", dbi_result_get_numrows(result));
222 printf("curr %llu\n", dbi_result_get_currow(result));
223 if (dbi_result_get_numrows(result)){
224 dbi_result_free(result);
225 continue;
226 }
227 if (!dbi_result_next_row(result)) {
228 printf("curr %llu\n", dbi_result_get_currow(result));
229 dbi_result_free(result);
230 printf("DB: Allocated TMSI %s for IMSI %s.\n", subscriber->tmsi, subscriber->imsi);
231 return db_set_subscriber(subscriber);
232 }
233 dbi_result_free(result);
234 }
235 return 0;
Jan Luebbe7398eb92008-12-27 00:45:41 +0000236}
237