mirror of
https://github.com/RangeNetworks/openbts.git
synced 2025-10-24 00:23:50 +00:00
Fixes #692 in public. This updates the SR (ip/port) for a user on every SIP transaction. Also standardizes SR interface to use just strings, no more external char*. Will modify actual SR later.
git-svn-id: http://wush.net/svn/range/software/public/openbts/trunk@3236 19bc5d8c-e614-43d4-8b26-e1612bc8e597
This commit is contained in:
@@ -201,26 +201,25 @@ void Control::LocationUpdatingController(const L3LocationUpdatingRequest* lur, L
|
||||
throw UnexpectedMessage();
|
||||
}
|
||||
LOG(INFO) << *resp;
|
||||
const char* new_imei = resp->mobileID().digits();
|
||||
if (!gTMSITable.IMEI(IMSI,new_imei)){
|
||||
string new_imei = resp->mobileID().digits();
|
||||
if (!gTMSITable.IMEI(IMSI,new_imei.c_str())){
|
||||
LOG(WARNING) << "failed access to TMSITable";
|
||||
}
|
||||
|
||||
//query subscriber registry for old imei, update if neccessary
|
||||
string name = string("IMSI") + IMSI;
|
||||
char* old_imei = gSubscriberRegistry.sqlQuery("hardware", "sip_buddies", "name", name.c_str());
|
||||
string old_imei = gSubscriberRegistry.imsiGet(name, "hardware");
|
||||
|
||||
//if we have a new imei and either there's no old one, or it is different...
|
||||
if (new_imei && (!old_imei || strncmp(old_imei,new_imei, 15) != 0)){
|
||||
ostringstream os2;
|
||||
os2 << "update sip_buddies set RRLPSupported = \"1\", hardware = \"" << new_imei << "\" where name = \"IMSI" << IMSI << "\"";
|
||||
if (!new_imei.empty() && (old_imei.empty() || old_imei != new_imei)){
|
||||
LOG(INFO) << "Updating IMSI" << IMSI << " to IMEI:" << new_imei;
|
||||
if (!gSubscriberRegistry.sqlUpdate(os2.str().c_str())) {
|
||||
LOG(INFO) << "SR update problem";
|
||||
if (!gSubscriberRegistry.imsiSet(name,"RRLPSupported", "1")) {
|
||||
LOG(INFO) << "SR RRLPSupported update problem";
|
||||
}
|
||||
if (!gSubscriberRegistry.imsiSet(name,"hardware", new_imei)) {
|
||||
LOG(INFO) << "SR hardware update problem";
|
||||
}
|
||||
}
|
||||
if (old_imei)
|
||||
free(old_imei);
|
||||
delete msg;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,14 +100,9 @@ RRLPServer::RRLPServer(L3MobileIdentity wMobileID, LogicalChannel *wDCCH)
|
||||
//if IMEI tagging enabled, check if this IMEI (which is updated elsewhere) has RRLP disabled
|
||||
//otherwise just go on
|
||||
if (gConfig.defines("Control.LUR.QueryIMEI")){
|
||||
unsigned int supported = 0;
|
||||
char* supported_str;
|
||||
//check supported bit
|
||||
supported_str = gSubscriberRegistry.sqlQuery("RRLPSupported", "sip_buddies", "name", name.c_str());
|
||||
if (supported_str)
|
||||
supported = atoi(supported_str);
|
||||
free(supported_str);
|
||||
if(!supported){
|
||||
string supported= gSubscriberRegistry.imsiGet(name, "RRLPSupported");
|
||||
if(supported.empty() || supported == "0"){
|
||||
LOG(INFO) << "RRLP not supported for " << name;
|
||||
trouble = true;
|
||||
}
|
||||
@@ -181,17 +176,12 @@ bool RRLPServer::transact()
|
||||
}
|
||||
|
||||
// quit if location decoded
|
||||
if (response.find("latitude") != response.end() && response.find("longitude") != response.end() && response.find("positionError") != response.end()) {
|
||||
ostringstream os;
|
||||
os << "insert into RRLP (name, latitude, longitude, error, time) values (" <<
|
||||
'"' << name << '"' << "," <<
|
||||
response["latitude"] << "," <<
|
||||
response["longitude"] << "," <<
|
||||
response["positionError"] << "," <<
|
||||
"datetime('now')"
|
||||
")";
|
||||
LOG(INFO) << os.str();
|
||||
if (!gSubscriberRegistry.sqlUpdate(os.str().c_str())) {
|
||||
if (response.find("latitude") != response.end() &&
|
||||
response.find("longitude") != response.end() &&
|
||||
response.find("positionError") != response.end()) {
|
||||
if (!gSubscriberRegistry.RRLPUpdate(name, response["latitude"],
|
||||
response["longitude"],
|
||||
response["positionError"])){
|
||||
LOG(INFO) << "SR update problem";
|
||||
return false;
|
||||
}
|
||||
@@ -241,7 +231,6 @@ bool RRLPServer::transact()
|
||||
}
|
||||
const unsigned MTI_RR_STATUS = 18;
|
||||
if (resp->MTI() == MTI_RR_STATUS) {
|
||||
ostringstream os2;
|
||||
int cause = resp->peekField(16, 8);
|
||||
delete resp;
|
||||
switch (cause) {
|
||||
@@ -250,8 +239,7 @@ bool RRLPServer::transact()
|
||||
//Rejection code only useful if we're gathering IMEIs
|
||||
if (gConfig.defines("Control.LUR.QueryIMEI")){
|
||||
// flag unsupported in SR so we don't waste time on it again
|
||||
os2 << "update sip_buddies set RRLPSupported = \"0\" where name = \"" << name.c_str() << "\"";
|
||||
if (!gSubscriberRegistry.sqlUpdate(os2.str().c_str())) {
|
||||
if (!gSubscriberRegistry.imsiSet(name, "RRLPSupported", "0")) {
|
||||
LOG(INFO) << "SR update problem";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <GSMConfig.h>
|
||||
#include <ControlCommon.h>
|
||||
#include <TransactionTable.h>
|
||||
#include <SubscriberRegistry.h>
|
||||
|
||||
#include <Sockets.h>
|
||||
|
||||
@@ -59,6 +60,15 @@ using namespace Control;
|
||||
void SIPMessageMap::write(const std::string& call_id, osip_message_t * msg)
|
||||
{
|
||||
LOG(DEBUG) << "call_id=" << call_id << " msg=" << msg;
|
||||
string name = osip_message_get_from(msg)->url->username;
|
||||
if (!gSubscriberRegistry.imsiSet(name, "ipaddr",
|
||||
osip_message_get_from(msg)->url->host)){
|
||||
LOG(INFO) << "SR ipaddr Update Problem";
|
||||
}
|
||||
if (!gSubscriberRegistry.imsiSet(name, "port",
|
||||
gConfig.getStr("SIP.Local.Port"))){
|
||||
LOG(INFO) << "SR port Update Problem";
|
||||
}
|
||||
OSIPMessageFIFO * fifo = mMap.readNoBlock(call_id);
|
||||
if( fifo==NULL ) {
|
||||
// FIXME -- If this write fails, send "call leg non-existent" response on SIP interface.
|
||||
|
||||
@@ -187,7 +187,7 @@ SubscriberRegistry::~SubscriberRegistry()
|
||||
|
||||
|
||||
|
||||
SubscriberRegistry::Status SubscriberRegistry::sqlLocal(const char *query, char **resultptr)
|
||||
SubscriberRegistry::Status SubscriberRegistry::sqlLocal(const char* query, char **resultptr)
|
||||
{
|
||||
LOG(INFO) << query;
|
||||
|
||||
@@ -219,36 +219,48 @@ SubscriberRegistry::Status SubscriberRegistry::sqlLocal(const char *query, char
|
||||
|
||||
|
||||
|
||||
char *SubscriberRegistry::sqlQuery(const char *unknownColumn, const char *table, const char *knownColumn, const char *knownValue)
|
||||
string SubscriberRegistry::sqlQuery(string unknownColumn, string table, string knownColumn, string knownValue)
|
||||
{
|
||||
char *result = NULL;
|
||||
SubscriberRegistry::Status st;
|
||||
ostringstream os;
|
||||
os << "select " << unknownColumn << " from " << table << " where " << knownColumn << " = \"" << knownValue << "\"";
|
||||
st = sqlLocal(os.str().c_str(), &result);
|
||||
if (st == SUCCESS) {
|
||||
if ((st == SUCCESS) && result) {
|
||||
LOG(INFO) << "result = " << result;
|
||||
return result;
|
||||
} else {
|
||||
return NULL;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
SubscriberRegistry::Status SubscriberRegistry::sqlUpdate(const char *stmt)
|
||||
SubscriberRegistry::Status SubscriberRegistry::sqlUpdate(string stmt)
|
||||
{
|
||||
LOG(INFO) << stmt;
|
||||
return sqlLocal(stmt, NULL);
|
||||
return sqlLocal(stmt.c_str(), NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *SubscriberRegistry::getIMSI(const char *ISDN)
|
||||
string SubscriberRegistry::imsiGet(string imsi, string key)
|
||||
{
|
||||
if (!ISDN) {
|
||||
string name = imsi.substr(0,4) == "IMSI" ? imsi : "IMSI" + imsi;
|
||||
return sqlQuery(key, "sip_buddies", "name", imsi);
|
||||
}
|
||||
|
||||
SubscriberRegistry::Status SubscriberRegistry::imsiSet(string imsi, string key, string value)
|
||||
{
|
||||
string name = imsi.substr(0,4) == "IMSI" ? imsi : "IMSI" + imsi;
|
||||
ostringstream os;
|
||||
os << "update sip_buddies set " << key << " = \"" << value << "\" where name = \"" << name << "\"";
|
||||
return sqlUpdate(os.str());
|
||||
}
|
||||
|
||||
string SubscriberRegistry::getIMSI(string ISDN)
|
||||
{
|
||||
if (ISDN.empty()) {
|
||||
LOG(WARNING) << "SubscriberRegistry::getIMSI attempting lookup of NULL ISDN";
|
||||
return NULL;
|
||||
return "";
|
||||
}
|
||||
LOG(INFO) << "getIMSI(" << ISDN << ")";
|
||||
return sqlQuery("dial", "dialdata_table", "exten", ISDN);
|
||||
@@ -256,11 +268,11 @@ char *SubscriberRegistry::getIMSI(const char *ISDN)
|
||||
|
||||
|
||||
|
||||
char *SubscriberRegistry::getCLIDLocal(const char* IMSI)
|
||||
string SubscriberRegistry::getCLIDLocal(string IMSI)
|
||||
{
|
||||
if (!IMSI) {
|
||||
if (IMSI.empty()) {
|
||||
LOG(WARNING) << "SubscriberRegistry::getCLIDLocal attempting lookup of NULL IMSI";
|
||||
return NULL;
|
||||
return "";
|
||||
}
|
||||
LOG(INFO) << "getCLIDLocal(" << IMSI << ")";
|
||||
return sqlQuery("callerid", "sip_buddies", "name", IMSI);
|
||||
@@ -268,11 +280,11 @@ char *SubscriberRegistry::getCLIDLocal(const char* IMSI)
|
||||
|
||||
|
||||
|
||||
char *SubscriberRegistry::getCLIDGlobal(const char* IMSI)
|
||||
string SubscriberRegistry::getCLIDGlobal(string IMSI)
|
||||
{
|
||||
if (!IMSI) {
|
||||
if (IMSI.empty()) {
|
||||
LOG(WARNING) << "SubscriberRegistry::getCLIDGlobal attempting lookup of NULL IMSI";
|
||||
return NULL;
|
||||
return "";
|
||||
}
|
||||
LOG(INFO) << "getCLIDGlobal(" << IMSI << ")";
|
||||
return sqlQuery("callerid", "sip_buddies", "name", IMSI);
|
||||
@@ -280,11 +292,11 @@ char *SubscriberRegistry::getCLIDGlobal(const char* IMSI)
|
||||
|
||||
|
||||
|
||||
char *SubscriberRegistry::getRegistrationIP(const char* IMSI)
|
||||
string SubscriberRegistry::getRegistrationIP(string IMSI)
|
||||
{
|
||||
if (!IMSI) {
|
||||
if (IMSI.empty()) {
|
||||
LOG(WARNING) << "SubscriberRegistry::getRegistrationIP attempting lookup of NULL IMSI";
|
||||
return NULL;
|
||||
return "";
|
||||
}
|
||||
LOG(INFO) << "getRegistrationIP(" << IMSI << ")";
|
||||
return sqlQuery("ipaddr", "sip_buddies", "name", IMSI);
|
||||
@@ -292,40 +304,33 @@ char *SubscriberRegistry::getRegistrationIP(const char* IMSI)
|
||||
|
||||
|
||||
|
||||
SubscriberRegistry::Status SubscriberRegistry::setRegTime(const char* IMSI)
|
||||
SubscriberRegistry::Status SubscriberRegistry::setRegTime(string IMSI)
|
||||
{
|
||||
if (!IMSI) {
|
||||
if (IMSI.empty()) {
|
||||
LOG(WARNING) << "SubscriberRegistry::setRegTime attempting set for NULL IMSI";
|
||||
return FAILURE;
|
||||
}
|
||||
unsigned now = (unsigned)time(NULL);
|
||||
ostringstream os;
|
||||
os << "update sip_buddies set regTime = " << now << " where name = " << '"' << IMSI << '"';
|
||||
return sqlUpdate(os.str().c_str());
|
||||
return sqlUpdate(os.str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
SubscriberRegistry::Status SubscriberRegistry::addUser(const char* IMSI, const char* CLID)
|
||||
SubscriberRegistry::Status SubscriberRegistry::addUser(string IMSI, string CLID)
|
||||
{
|
||||
if (!IMSI) {
|
||||
if (IMSI.empty()) {
|
||||
LOG(WARNING) << "SubscriberRegistry::addUser attempting add of NULL IMSI";
|
||||
return FAILURE;
|
||||
}
|
||||
if (!CLID) {
|
||||
if (CLID.empty()) {
|
||||
LOG(WARNING) << "SubscriberRegistry::addUser attempting add of NULL CLID";
|
||||
return FAILURE;
|
||||
}
|
||||
//this was a memory leak -kurtis
|
||||
char* old_imsi = getIMSI(CLID);
|
||||
char* old_clid = getCLIDLocal(IMSI);
|
||||
if (old_imsi || old_clid) {
|
||||
if (!getIMSI(CLID).empty() || !getCLIDLocal(IMSI).empty()) {
|
||||
LOG(WARNING) << "SubscriberRegistry::addUser attempting user duplication";
|
||||
// technically this is a failure, but I don't want it to keep trying
|
||||
if (old_imsi)
|
||||
free(old_imsi);
|
||||
if (old_clid)
|
||||
free(old_clid);
|
||||
//technically failure, but let's move on
|
||||
return SUCCESS;
|
||||
}
|
||||
LOG(INFO) << "addUser(" << IMSI << "," << CLID << ")";
|
||||
@@ -352,40 +357,49 @@ SubscriberRegistry::Status SubscriberRegistry::addUser(const char* IMSI, const c
|
||||
os << "\"" << "127.0.0.1" << "\"";
|
||||
os << ")";
|
||||
os << ";";
|
||||
SubscriberRegistry::Status st = sqlUpdate(os.str().c_str());
|
||||
SubscriberRegistry::Status st = sqlUpdate(os.str());
|
||||
ostringstream os2;
|
||||
os2 << "insert into dialdata_table (exten, dial) values (";
|
||||
os2 << "\"" << CLID << "\"";
|
||||
os2 << ",";
|
||||
os2 << "\"" << IMSI << "\"";
|
||||
os2 << ")";
|
||||
SubscriberRegistry::Status st2 = sqlUpdate(os2.str().c_str());
|
||||
SubscriberRegistry::Status st2 = sqlUpdate(os2.str());
|
||||
return st == SUCCESS && st2 == SUCCESS ? SUCCESS : FAILURE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *SubscriberRegistry::mapCLIDGlobal(const char *local)
|
||||
string SubscriberRegistry::mapCLIDGlobal(string local)
|
||||
{
|
||||
if (!local) {
|
||||
if (local.empty()) {
|
||||
LOG(WARNING) << "SubscriberRegistry::mapCLIDGlobal attempting lookup of NULL local";
|
||||
return NULL;
|
||||
return "";
|
||||
}
|
||||
LOG(INFO) << "mapCLIDGlobal(" << local << ")";
|
||||
char *IMSI = getIMSI(local);
|
||||
if (!IMSI) return NULL;
|
||||
char *global = getCLIDGlobal(IMSI);
|
||||
free(IMSI);
|
||||
return global;
|
||||
string IMSI = getIMSI(local);
|
||||
if (IMSI.empty()) return "";
|
||||
return getCLIDGlobal(IMSI);
|
||||
}
|
||||
|
||||
SubscriberRegistry::Status SubscriberRegistry::RRLPUpdate(string name, string lat, string lon, string err){
|
||||
ostringstream os;
|
||||
os << "insert into RRLP (name, latitude, longitude, error, time) values (" <<
|
||||
'"' << name << '"' << "," <<
|
||||
lat << "," <<
|
||||
lon << "," <<
|
||||
err << "," <<
|
||||
"datetime('now')"
|
||||
")";
|
||||
LOG(INFO) << os.str();
|
||||
return sqlUpdate(os.str());
|
||||
}
|
||||
|
||||
|
||||
bool SubscriberRegistry::useGateway(const char* ISDN)
|
||||
bool SubscriberRegistry::useGateway(string ISDN)
|
||||
{
|
||||
// FIXME -- Do something more general in Asterisk.
|
||||
// This is a hack for Burning Man.
|
||||
int cmp = strncmp(ISDN,"88351000125",11);
|
||||
int cmp = strncmp(ISDN.c_str(),"88351000125",11);
|
||||
return cmp!=0;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,77 +72,74 @@ class SubscriberRegistry {
|
||||
/**
|
||||
Resolve an ISDN or other numeric address to an IMSI.
|
||||
@param ISDN Any numeric address, E.164, local extension, etc.
|
||||
@return A C-string to be freed by the caller,
|
||||
NULL if the ISDN cannot be resolved.
|
||||
*/
|
||||
char* getIMSI(const char* ISDN);
|
||||
string getIMSI(string ISDN);
|
||||
|
||||
/**
|
||||
Given an IMSI, return the local CLID, which should be a numeric address.
|
||||
@param IMSI The subscriber IMSI.
|
||||
@return A C-string to be freed by the caller,
|
||||
NULL if the IMSI isn't found.
|
||||
*/
|
||||
char* getCLIDLocal(const char* IMSI);
|
||||
string getCLIDLocal(string IMSI);
|
||||
|
||||
/**
|
||||
Given an IMSI, return the global CLID, which should be a numeric address.
|
||||
@param IMSI The subscriber IMSI.
|
||||
@return A C-string to be freed by the caller,
|
||||
NULL if the IMSI isn't found.
|
||||
|
||||
*/
|
||||
char* getCLIDGlobal(const char* IMSI);
|
||||
string getCLIDGlobal(string IMSI);
|
||||
|
||||
/**
|
||||
Given an IMSI, return the IP address of the most recent registration.
|
||||
@param IMSI The subscriber IMSI
|
||||
@return A C-string to be freed by the caller, "111.222.333.444:port",
|
||||
NULL if the ISMI isn't registered.
|
||||
@return The Registration IP for this IMSI, "111.222.333.444:port",
|
||||
|
||||
*/
|
||||
char* getRegistrationIP(const char* IMSI);
|
||||
string getRegistrationIP(string IMSI);
|
||||
|
||||
/**
|
||||
Set a specific variable indexed by imsi from sip_buddies
|
||||
@param imsi The user's IMSI or SIP username.
|
||||
@param key to index into table
|
||||
*/
|
||||
string imsiGet(string imsi, string key);
|
||||
|
||||
/**
|
||||
Set a specific variable indexed by imsi_from sip_buddies
|
||||
@param imsi The user's IMSI or SIP username.
|
||||
@param key to index into table
|
||||
@param value to set indexed by the key
|
||||
*/
|
||||
Status imsiSet(string imsi, string key, string value);
|
||||
|
||||
/**
|
||||
Add a new user to the SubscriberRegistry.
|
||||
@param IMSI The user's IMSI or SIP username.
|
||||
@param CLID The user's local CLID.
|
||||
*/
|
||||
Status addUser(const char* IMSI, const char* CLID);
|
||||
Status addUser(string IMSI, string CLID);
|
||||
|
||||
|
||||
/**
|
||||
Set the current time as the time of the most recent registration for an IMSI.
|
||||
@param IMSI The user's IMSI or SIP username.
|
||||
*/
|
||||
Status setRegTime(const char* IMSI);
|
||||
Status setRegTime(string IMSI);
|
||||
|
||||
|
||||
char *mapCLIDGlobal(const char *local);
|
||||
string mapCLIDGlobal(string local);
|
||||
|
||||
|
||||
bool useGateway(const char* ISDN);
|
||||
|
||||
|
||||
/* Generic Update/Get functions.
|
||||
Make sure your SQL is generic too */
|
||||
/**
|
||||
Run an sql query (select unknownColumn from table where knownColumn = knownValue).
|
||||
@param unknownColumn The column whose value you want.
|
||||
@param table The table to look in.
|
||||
@param knownColumn The column with the value you know.
|
||||
@param knownValue The known value of knownColumn.
|
||||
*/
|
||||
char *sqlQuery(const char *unknownColumn, const char *table, const char *knownColumn, const char *knownValue);
|
||||
|
||||
bool useGateway(string ISDN);
|
||||
|
||||
|
||||
/**
|
||||
Run an sql update.
|
||||
@param stmt The update statement.
|
||||
Update the RRLP location for user
|
||||
@param name IMSI to be updated
|
||||
@param lat Latitude
|
||||
@param lon Longitude
|
||||
@param err Approximate Error
|
||||
*/
|
||||
Status sqlUpdate(const char *stmt);
|
||||
|
||||
|
||||
|
||||
Status RRLPUpdate(string name, string lat, string lon, string err);
|
||||
|
||||
private:
|
||||
|
||||
@@ -152,9 +149,15 @@ class SubscriberRegistry {
|
||||
@param stmt The sql statements.
|
||||
@param resultptr Set this to point to the result of executing the statements.
|
||||
*/
|
||||
Status sqlLocal(const char *stmt, char **resultptr);
|
||||
Status sqlLocal(const char* stmt, char **resultptr);
|
||||
|
||||
string sqlQuery(string unknownColumn, string table, string knownColumn, string knownValue);
|
||||
|
||||
/**
|
||||
Run an sql update.
|
||||
@param stmt The update statement.
|
||||
*/
|
||||
Status sqlUpdate(string stmt);
|
||||
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user