change most len-as-short+bytes strings to vli+bytes; add device model

to what's passed for device registration, and store it in a new column
in devices table.
This commit is contained in:
Eric House 2013-08-25 21:20:26 -07:00
parent d10e9f6235
commit 063b01d3d8
6 changed files with 116 additions and 99 deletions

View file

@ -24,14 +24,15 @@ import android.app.Service;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.DatagramPacket; import java.net.DatagramPacket;
import java.net.DatagramSocket; import java.net.DatagramSocket;
import java.net.InetAddress; import java.net.InetAddress;
@ -494,24 +495,24 @@ public class RelayService extends XWService
int unavail = dis.readInt(); int unavail = dis.readInt();
DbgUtils.logf( "relay unvailable for another %d seconds", DbgUtils.logf( "relay unvailable for another %d seconds",
unavail ); unavail );
String str = getStringWithLength( dis ); String str = getVLIString( dis );
sendResult( MultiEvent.RELAY_ALERT, str ); sendResult( MultiEvent.RELAY_ALERT, str );
break; break;
case XWPDEV_ALERT: case XWPDEV_ALERT:
str = getStringWithLength( dis ); str = getVLIString( dis );
Intent intent = GamesList.makeAlertIntent( this, str ); Intent intent = GamesList.makeAlertIntent( this, str );
Utils.postNotification( this, intent, Utils.postNotification( this, intent,
R.string.relay_alert_title, R.string.relay_alert_title,
str, str.hashCode() ); str, str.hashCode() );
break; break;
case XWPDEV_BADREG: case XWPDEV_BADREG:
str = getStringWithLength( dis ); str = getVLIString( dis );
DbgUtils.logf( "bad relayID \"%s\" reported", str ); DbgUtils.logf( "bad relayID \"%s\" reported", str );
XWPrefs.clearRelayDevID( this ); XWPrefs.clearRelayDevID( this );
registerWithRelay(); registerWithRelay();
break; break;
case XWPDEV_REGRSP: case XWPDEV_REGRSP:
str = getStringWithLength( dis ); str = getVLIString( dis );
m_maxIntervalSeconds = dis.readShort(); m_maxIntervalSeconds = dis.readShort();
DbgUtils.logf( "got relayid %s, maxInterval %d", str, DbgUtils.logf( "got relayid %s, maxInterval %d", str,
m_maxIntervalSeconds ); m_maxIntervalSeconds );
@ -553,12 +554,11 @@ public class RelayService extends XWService
try { try {
DataOutputStream out = addProtoAndCmd( bas, XWRelayReg.XWPDEV_REG ); DataOutputStream out = addProtoAndCmd( bas, XWRelayReg.XWPDEV_REG );
out.writeByte( typ[0] ); out.writeByte( typ[0] );
out.writeShort( devid.length() ); writeVLIString( out, devid );
out.writeBytes( devid );
out.writeShort( GitVersion.CLIENT_VERS_RELAY ); out.writeShort( GitVersion.CLIENT_VERS_RELAY );
out.writeShort( GitVersion.VERS.length() ); writeVLIString( out, GitVersion.VERS );
out.writeBytes( GitVersion.VERS ); writeVLIString( out, Build.MODEL );
postPacket( bas ); postPacket( bas );
} catch ( java.io.IOException ioe ) { } catch ( java.io.IOException ioe ) {
@ -572,8 +572,7 @@ public class RelayService extends XWService
try { try {
DataOutputStream out = addProtoAndCmd( bas, reg ); DataOutputStream out = addProtoAndCmd( bas, reg );
String devid = getDevID( null ); String devid = getDevID( null );
out.writeShort( devid.length() ); writeVLIString( out, devid );
out.writeBytes( devid );
postPacket( bas ); postPacket( bas );
} catch ( java.io.IOException ioe ) { } catch ( java.io.IOException ioe ) {
DbgUtils.loge( ioe ); DbgUtils.loge( ioe );
@ -656,10 +655,10 @@ public class RelayService extends XWService
return result; return result;
} }
private String getStringWithLength( DataInputStream dis ) private String getVLIString( DataInputStream dis )
throws java.io.IOException throws java.io.IOException
{ {
short len = dis.readShort(); int len = vli2un( dis );
byte[] tmp = new byte[len]; byte[] tmp = new byte[len];
dis.read( tmp ); dis.read( tmp );
String result = new String( tmp ); String result = new String( tmp );
@ -1000,6 +999,14 @@ public class RelayService extends XWService
return result; return result;
} }
private static void writeVLIString( DataOutputStream os, String str )
throws java.io.IOException
{
int len = str.length();
un2vli( len, os );
os.writeBytes( str );
}
/* Timers: /* Timers:
* *
* Two goals: simulate the GCM experience for those who don't have * Two goals: simulate the GCM experience for those who don't have

View file

@ -42,7 +42,7 @@ static RelayConStorage* getStorage( LaunchParams* params );
static XP_U32 hostNameToIP( const XP_UCHAR* name ); static XP_U32 hostNameToIP( const XP_UCHAR* name );
static void relaycon_receive( void* closure, int socket ); static void relaycon_receive( void* closure, int socket );
static ssize_t sendIt( RelayConStorage* storage, const XP_U8* msgbuf, XP_U16 len ); static ssize_t sendIt( RelayConStorage* storage, const XP_U8* msgbuf, XP_U16 len );
static size_t addStrWithLength( XP_U8* buf, XP_U8* end, const XP_UCHAR* str ); static size_t addVLIStr( XP_U8* buf, size_t len, const XP_UCHAR* str );
static void getNetString( const XP_U8** ptr, XP_U16 len, XP_UCHAR* buf ); static void getNetString( const XP_U8** ptr, XP_U16 len, XP_UCHAR* buf );
static XP_U16 getNetShort( const XP_U8** ptr ); static XP_U16 getNetShort( const XP_U8** ptr );
static XP_U32 getNetLong( const XP_U8** ptr ); static XP_U32 getNetLong( const XP_U8** ptr );
@ -90,7 +90,8 @@ relaycon_reg( LaunchParams* params, const XP_UCHAR* devID, DevIDType typ )
indx += writeDevID( &tmpbuf[indx], sizeof(tmpbuf) - indx, devID ); indx += writeDevID( &tmpbuf[indx], sizeof(tmpbuf) - indx, devID );
indx += writeShort( &tmpbuf[indx], sizeof(tmpbuf) - indx, indx += writeShort( &tmpbuf[indx], sizeof(tmpbuf) - indx,
INITIAL_CLIENT_VERS ); INITIAL_CLIENT_VERS );
indx += addStrWithLength( &tmpbuf[indx], tmpbuf + sizeof(tmpbuf), SVN_REV ); indx += addVLIStr( &tmpbuf[indx], sizeof(tmpbuf) - indx, SVN_REV );
indx += addVLIStr( &tmpbuf[indx], sizeof(tmpbuf) - indx, "linux box" );
sendIt( storage, tmpbuf, indx ); sendIt( storage, tmpbuf, indx );
} }
@ -158,7 +159,7 @@ relaycon_requestMsgs( LaunchParams* params, const XP_UCHAR* devID )
XP_U8 tmpbuf[128]; XP_U8 tmpbuf[128];
int indx = 0; int indx = 0;
indx += writeHeader( storage, tmpbuf, XWPDEV_RQSTMSGS ); indx += writeHeader( storage, tmpbuf, XWPDEV_RQSTMSGS );
indx += addStrWithLength( &tmpbuf[indx], tmpbuf + sizeof(tmpbuf), devID ); indx += addVLIStr( &tmpbuf[indx], sizeof(tmpbuf) - indx, devID );
sendIt( storage, tmpbuf, indx ); sendIt( storage, tmpbuf, indx );
} }
@ -218,7 +219,10 @@ relaycon_receive( void* closure, int socket )
sendAckIf( storage, &header ); sendAckIf( storage, &header );
switch( header.cmd ) { switch( header.cmd ) {
case XWPDEV_REGRSP: { case XWPDEV_REGRSP: {
XP_U16 len = getNetShort( &ptr ); uint32_t len;
if ( !vli2un( &ptr, &len ) ) {
assert(0);
}
XP_UCHAR devID[len+1]; XP_UCHAR devID[len+1];
getNetString( &ptr, len, devID ); getNetString( &ptr, len, devID );
XP_U16 maxInterval = getNetShort( &ptr ); XP_U16 maxInterval = getNetShort( &ptr );
@ -241,9 +245,13 @@ relaycon_receive( void* closure, int socket )
case XWPDEV_UNAVAIL: { case XWPDEV_UNAVAIL: {
XP_U32 unavail = getNetLong( &ptr ); XP_U32 unavail = getNetLong( &ptr );
XP_LOGF( "%s: unavail = %lu", __func__, unavail ); XP_LOGF( "%s: unavail = %lu", __func__, unavail );
XP_U16 len = getNetShort( &ptr ); uint32_t len;
if ( !vli2un( &ptr, &len ) ) {
assert(0);
}
XP_UCHAR buf[len+1]; XP_UCHAR buf[len+1];
getNetString( &ptr, len, buf ); getNetString( &ptr, len, buf );
(*storage->procs.msgErrorMsg)( storage->procsClosure, buf ); (*storage->procs.msgErrorMsg)( storage->procsClosure, buf );
break; break;
} }
@ -257,11 +265,12 @@ relaycon_receive( void* closure, int socket )
break; break;
} }
case XWPDEV_ALERT: { case XWPDEV_ALERT: {
XP_U16 len = getNetShort( &ptr ); uint32_t len;
unsigned char buf[len + 1]; if ( !vli2un( &ptr, &len ) ) {
memcpy( buf, ptr, len ); assert(0);
ptr += len; }
buf[len] = '\0'; XP_UCHAR buf[len + 1];
getNetString( &ptr, len, buf );
XP_LOGF( "%s: got message: %s", __func__, buf ); XP_LOGF( "%s: got message: %s", __func__, buf );
break; break;
} }
@ -323,22 +332,23 @@ sendIt( RelayConStorage* storage, const XP_U8* msgbuf, XP_U16 len )
} }
static size_t static size_t
addStrWithLength( XP_U8* buf, XP_U8* end, const XP_UCHAR* str ) addVLIStr( XP_U8* buf, size_t buflen, const XP_UCHAR* str )
{ {
XP_U16 len = !!str? XP_STRLEN( str ) : 0; uint32_t len = !!str? strlen( str ) : 0;
if ( buf + len + sizeof(len) <= end ) { uint8_t nbuf[5];
XP_U16 lenNBO = htons( len ); size_t nsize = un2vli( len, nbuf );
XP_MEMCPY( buf, &lenNBO, sizeof(lenNBO) ); if ( nsize + len <= buflen ) {
buf += sizeof(lenNBO); memcpy( buf, nbuf, nsize );
buf += nsize;
XP_MEMCPY( buf, str, len ); XP_MEMCPY( buf, str, len );
} }
return len + sizeof(len); return nsize + len;
} }
static size_t static size_t
writeDevID( XP_U8* buf, size_t len, const XP_UCHAR* str ) writeDevID( XP_U8* buf, size_t len, const XP_UCHAR* str )
{ {
return addStrWithLength( buf, buf + len, str ); return addVLIStr( buf, len, str );
} }
static size_t static size_t

View file

@ -340,7 +340,7 @@ DBMgr::AllDevsAckd( const char* const connName )
// already there. // already there.
DevIDRelay DevIDRelay
DBMgr::RegisterDevice( const DevID* host, int clientVersion, DBMgr::RegisterDevice( const DevID* host, int clientVersion,
const char* const desc ) const char* const desc, const char* const model )
{ {
DevIDRelay devID; DevIDRelay devID;
assert( host->m_devIDType != ID_TYPE_NONE ); assert( host->m_devIDType != ID_TYPE_NONE );
@ -368,14 +368,14 @@ DBMgr::RegisterDevice( const DevID* host, int clientVersion,
const char* command = "INSERT INTO " DEVICES_TABLE const char* command = "INSERT INTO " DEVICES_TABLE
" (id, devType, devid, clntVers, versDesc)" " (id, devType, devid, clntVers, versDesc)"
" VALUES( $1, $2, $3, $4, $5 )"; " VALUES( $1, $2, $3, $4, $5 )";
int nParams = 5; int nParams = 6;
char* paramValues[nParams]; char* paramValues[nParams];
char buf[1024]; char buf[1024];
formatParams( paramValues, nParams, formatParams( paramValues, nParams,
"%d"DELIM"%d"DELIM"%s"DELIM"%d"DELIM"%s", "%d"DELIM"%d"DELIM"%s"DELIM"%d"DELIM"%s"DELIM"%s",
buf, sizeof(buf), devID, host->m_devIDType, buf, sizeof(buf), devID, host->m_devIDType,
host->m_devIDString.c_str(), clientVersion, host->m_devIDString.c_str(), clientVersion,
desc ); desc, model );
PGresult* result = PQexecParams( getThreadConn(), command, PGresult* result = PQexecParams( getThreadConn(), command,
nParams, NULL, nParams, NULL,
@ -396,12 +396,13 @@ DBMgr::RegisterDevice( const DevID* host, int clientVersion,
DevIDRelay DevIDRelay
DBMgr::RegisterDevice( const DevID* host ) DBMgr::RegisterDevice( const DevID* host )
{ {
return RegisterDevice( host, 0, "" ); return RegisterDevice( host, 0, NULL, NULL );
} }
bool bool
DBMgr::UpdateDevice( DevIDRelay relayID, int clientVersion, DBMgr::UpdateDevice( DevIDRelay relayID, int clientVersion,
const char* const desc, bool check ) const char* const desc, const char* const model,
bool check )
{ {
bool exists = !check; bool exists = !check;
if ( !exists ) { if ( !exists ) {
@ -417,6 +418,9 @@ DBMgr::UpdateDevice( DevIDRelay relayID, int clientVersion,
string_printf( query, ", clntVers=%d, versDesc='%s'", string_printf( query, ", clntVers=%d, versDesc='%s'",
clientVersion, desc ); clientVersion, desc );
} }
if ( NULL != model && '\0' != model[0] ) {
string_printf( query, ", model='%s'", model );
}
string_printf( query, " WHERE id = %d", relayID ); string_printf( query, " WHERE id = %d", relayID );
execSql( query ); execSql( query );
} }
@ -426,7 +430,7 @@ DBMgr::UpdateDevice( DevIDRelay relayID, int clientVersion,
bool bool
DBMgr::UpdateDevice( DevIDRelay relayID ) DBMgr::UpdateDevice( DevIDRelay relayID )
{ {
return UpdateDevice( relayID, 0, NULL, false ); return UpdateDevice( relayID, 0, NULL, NULL, false );
} }
HostID HostID

View file

@ -82,9 +82,10 @@ class DBMgr {
DevIDRelay RegisterDevice( const DevID* host ); DevIDRelay RegisterDevice( const DevID* host );
DevIDRelay RegisterDevice( const DevID* host, int clientVersion, DevIDRelay RegisterDevice( const DevID* host, int clientVersion,
const char* const desc ); const char* const desc, const char* const model );
bool UpdateDevice( DevIDRelay relayID, int clientVersion, bool UpdateDevice( DevIDRelay relayID, int clientVersion,
const char* const desc, bool check ); const char* const desc, const char* const model,
bool check );
HostID AddDevice( const char* const connName, HostID curID, int clientVersion, HostID AddDevice( const char* const connName, HostID curID, int clientVersion,
int nToAdd, unsigned short seed, const AddrInfo* addr, int nToAdd, unsigned short seed, const AddrInfo* addr,

View file

@ -294,23 +294,6 @@ getNetString( const unsigned char** bufpp, const unsigned char* end, string& out
return success; return success;
} }
static bool
getShortInitString( const unsigned char** bufpp, const unsigned char* end,
string& out )
{
bool success;
uint16_t len;
success = getNetShort( bufpp, end, &len );
if ( success ) {
success = *bufpp + len <= end;
if ( success ) {
out.append( (const char*)*bufpp, len );
*bufpp += len;
}
}
return success;
}
static bool static bool
vli2un( const unsigned char** bufpp, const unsigned char* end, uint32_t* out ) vli2un( const unsigned char** bufpp, const unsigned char* end, uint32_t* out )
{ {
@ -338,11 +321,26 @@ vli2un( const unsigned char** bufpp, const unsigned char* end, uint32_t* out )
return success; return success;
} }
static bool
getVLIString( const unsigned char** bufpp, const unsigned char* end,
string& out )
{
bool success = false;
uint32_t len;
if ( vli2un( bufpp, end, &len ) && *bufpp + len <= end ) {
out.append( (const char*)*bufpp, len );
*bufpp += len;
success = true;
logf( XW_LOGINFO, "%s=>%s", __func__, out.c_str() );
}
return success;
}
static bool static bool
getRelayDevID( const unsigned char** bufpp, const unsigned char* end, getRelayDevID( const unsigned char** bufpp, const unsigned char* end,
DevID& devID ) DevID& devID )
{ {
return getShortInitString( bufpp, end, devID.m_devIDString ); return getVLIString( bufpp, end, devID.m_devIDString );
} }
static bool static bool
@ -719,11 +717,12 @@ post_message( DevIDRelay devid, const char* message, OnMsgAckProc proc,
vector<uint8_t> packet; vector<uint8_t> packet;
uint32_t packetID; uint32_t packetID;
XWRelayReg cmd = XWPDEV_ALERT; XWRelayReg cmd = XWPDEV_ALERT;
short len = strlen( message );
short netLen = htons( len ); uint32_t len = strlen( message );
assemble_packet( packet, &packetID, cmd, &netLen, sizeof(netLen), uint8_t lenbuf[5];
message, strlen(message), size_t lenlen = un2vli( len, lenbuf );
NULL ); assemble_packet( packet, &packetID, cmd, lenbuf, lenlen,
message, len, NULL );
const AddrInfo::AddrUnion* addru = DevMgr::Get()->get( devid ); const AddrInfo::AddrUnion* addru = DevMgr::Get()->get( devid );
bool canSendNow = !!addru; bool canSendNow = !!addru;
@ -1427,33 +1426,36 @@ proxy_thread_proc( UdpThreadClosure* utc )
XWThreadPool::GetTPool()->CloseSocket( addr ); XWThreadPool::GetTPool()->CloseSocket( addr );
} // proxy_thread_proc } // proxy_thread_proc
static size_t
addVLIStr( uint8_t* ptr, const char* str )
{
uint32_t len = strlen( str );
size_t indx = un2vli( len, ptr );
memcpy( &ptr[indx], str, len );
return indx + len;
}
static short static short
addRegID( unsigned char* ptr, DevIDRelay relayID ) addRegID( unsigned char* ptr, DevIDRelay relayID )
{ {
short used = 0;
char idbuf[9]; char idbuf[9];
int idLen = snprintf( idbuf, sizeof(idbuf), "%.8X", relayID ); (void)snprintf( idbuf, sizeof(idbuf), "%.8X", relayID );
short lenNBO = htons(idLen); return addVLIStr( ptr, idbuf );
memcpy( &ptr[used], &lenNBO, sizeof(lenNBO) );
used += sizeof(lenNBO);
memcpy( &ptr[used], idbuf, idLen );
used += idLen;
return used;
} }
static void static void
registerDevice( const DevID* devID, const AddrInfo* addr, int clientVers, registerDevice( const DevID* devID, const AddrInfo* addr, int clientVers,
string devDesc ) string& devDesc, string& model )
{ {
DevIDRelay relayID; DevIDRelay relayID;
DBMgr* dbMgr = DBMgr::Get(); DBMgr* dbMgr = DBMgr::Get();
short indx = 0; short indx = 0;
unsigned char buf[32]; uint8_t buf[32];
if ( ID_TYPE_RELAY == devID->m_devIDType ) { // known to us; just update the time if ( ID_TYPE_RELAY == devID->m_devIDType ) { // known to us; just update the time
relayID = devID->asRelayID(); relayID = devID->asRelayID();
if ( dbMgr->UpdateDevice( relayID, clientVers, devDesc.c_str(), if ( dbMgr->UpdateDevice( relayID, clientVers, devDesc.c_str(),
true ) ) { model.c_str(), true ) ) {
int nMsgs = dbMgr->CountStoredMessages( relayID ); int nMsgs = dbMgr->CountStoredMessages( relayID );
if ( 0 < nMsgs ) { if ( 0 < nMsgs ) {
send_havemsgs( addr ); send_havemsgs( addr );
@ -1465,7 +1467,8 @@ registerDevice( const DevID* devID, const AddrInfo* addr, int clientVers,
relayID = DBMgr::DEVID_NONE; relayID = DBMgr::DEVID_NONE;
} }
} else { } else {
relayID = dbMgr->RegisterDevice( devID, clientVers, devDesc.c_str() ); relayID = dbMgr->RegisterDevice( devID, clientVers, devDesc.c_str(),
model.c_str() );
} }
if ( DBMgr::DEVID_NONE != relayID ) { if ( DBMgr::DEVID_NONE != relayID ) {
@ -1573,9 +1576,12 @@ handle_udp_packet( UdpThreadClosure* utc )
if ( getRelayDevID( &ptr, end, devID ) ) { if ( getRelayDevID( &ptr, end, devID ) ) {
uint16_t clientVers; uint16_t clientVers;
string devDesc; string devDesc;
string model;
if ( getNetShort( &ptr, end, &clientVers ) if ( getNetShort( &ptr, end, &clientVers )
&& getShortInitString( &ptr, end, devDesc ) ) { && getVLIString( &ptr, end, devDesc )
registerDevice( &devID, utc->addr(), clientVers, devDesc ); && getVLIString( &ptr, end, model ) ) {
registerDevice( &devID, utc->addr(), clientVers,
devDesc, model );
} }
} }
break; break;
@ -1620,23 +1626,14 @@ handle_udp_packet( UdpThreadClosure* utc )
} }
case XWPDEV_KEEPALIVE: case XWPDEV_KEEPALIVE:
case XWPDEV_RQSTMSGS: { case XWPDEV_RQSTMSGS: {
unsigned short idLen;
if ( !getNetShort( &ptr, end, &idLen ) ) {
break;
}
if ( end - ptr > idLen ) {
logf( XW_LOGERROR, "full devID not received" );
break;
}
DevID devID( ID_TYPE_RELAY ); DevID devID( ID_TYPE_RELAY );
devID.m_devIDString.append( (const char*)ptr, idLen ); if ( getVLIString( &ptr, end, devID.m_devIDString ) ) {
ptr += idLen; const AddrInfo* addr = utc->addr();
DevMgr::Get()->rememberDevice( devID.asRelayID(), addr );
const AddrInfo* addr = utc->addr(); if ( XWPDEV_RQSTMSGS == header.cmd ) {
DevMgr::Get()->rememberDevice( devID.asRelayID(), addr ); retrieveMessages( devID, addr );
}
if ( XWPDEV_RQSTMSGS == header.cmd ) {
retrieveMessages( devID, addr );
} }
break; break;
} }
@ -1793,11 +1790,8 @@ maint_str_loop( int udpsock, const char* str )
{ {
logf( XW_LOGINFO, "%s()", __func__ ); logf( XW_LOGINFO, "%s()", __func__ );
assert( -1 != udpsock ); assert( -1 != udpsock );
short len = strlen(str); uint8_t outbuf[1024];
unsigned char outbuf[sizeof(len) + len]; size_t indx = addVLIStr( &outbuf[0], str );
short lenNS = htons( len );
memcpy( &outbuf[0], &lenNS, sizeof(lenNS) );
memcpy( &outbuf[0+sizeof(len)], str, len );
fd_set rfds; fd_set rfds;
for ( ; ; ) { for ( ; ; ) {
@ -1825,7 +1819,7 @@ maint_str_loop( int udpsock, const char* str )
if ( getHeader( &ptr, ptr + nRead, &header ) ) { if ( getHeader( &ptr, ptr + nRead, &header ) ) {
send_via_udp( udpsock, &saddr.u.addr, NULL, XWPDEV_UNAVAIL, send_via_udp( udpsock, &saddr.u.addr, NULL, XWPDEV_UNAVAIL,
&unavail, sizeof(unavail), &unavail, sizeof(unavail),
outbuf, sizeof(outbuf), outbuf, indx,
NULL ); NULL );
} else { } else {
logf( XW_LOGERROR, "unexpected data" ); logf( XW_LOGERROR, "unexpected data" );

View file

@ -85,6 +85,7 @@ id INTEGER UNIQUE PRIMARY KEY
,clntVers INTEGER ,clntVers INTEGER
,versDesc TEXT ,versDesc TEXT
,devid TEXT ,devid TEXT
,model TEXT
,ctime TIMESTAMP DEFAULT CURRENT_TIMESTAMP ,ctime TIMESTAMP DEFAULT CURRENT_TIMESTAMP
,mtime TIMESTAMP ,mtime TIMESTAMP
,unreg BOOLEAN DEFAULT FALSE ,unreg BOOLEAN DEFAULT FALSE