1443 lines
44 KiB
C
1443 lines
44 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <sys/time.h>
|
|
#include <uv.h>
|
|
#include <dbus/dbus.h>
|
|
#include <errno.h>
|
|
#include <time.h>
|
|
#include <sqlite3.h>
|
|
#include <uthash/uthash.h>
|
|
#include <uthash/utlist.h>
|
|
#include <uthash/utstring.h>
|
|
#include <cjson/cJSON.h>
|
|
|
|
#include "log.h"
|
|
#include "crypto.h"
|
|
#include "json_struct.h"
|
|
#include "config_engine.h"
|
|
#include "skins_res.h"
|
|
#include "inet_api.h"
|
|
|
|
#define MAX_DOWNLOAD_ITEMS (10)
|
|
|
|
#define DEBUG_SQL_CMD (0)
|
|
|
|
typedef enum
|
|
{
|
|
STATUS_CREATE_NEW = 0,
|
|
STATUS_DOWNLOADING,
|
|
STATUS_DOWNLOADED,
|
|
} RES_DOWNLOAD_STATUS;
|
|
|
|
typedef enum
|
|
{
|
|
UPG_STATUS_ADDNEW = (1 << 0),
|
|
UPG_STATUS_DL_NEW = (1 << 1),
|
|
UPG_STATUS_DOWNLOADED = (1 << 2),
|
|
} UPGRADE_RES_STATUS;
|
|
|
|
typedef struct
|
|
{
|
|
char* pKeyName;
|
|
char* pResPath;
|
|
|
|
UT_hash_handle hh; ///< UT Hash handle
|
|
} SKINS_CACHE_ITEM, *PSKINS_CACHE_ITEM;
|
|
static uv_rwlock_t g_SkinCacheRwLock;
|
|
|
|
#ifdef PLATFORM_CPU
|
|
#define DOWNLOAD_RES_ROOT_PATH (DEF_SKINS_ROOT_PATH)
|
|
#else
|
|
#define DOWNLOAD_RES_ROOT_PATH ("/mnt/UDISK/resources/")
|
|
#endif
|
|
|
|
//select * FROM upgrade_skin WHERE resVersion == 4 ORDER BY resType DESC, RANDOM() LIMIT 1
|
|
//#define SKIN_GET_SQL_CMD ("")
|
|
|
|
#define ATTACH_DB_SQL_CMD ("ATTACH \'%s\' AS \'%s\'")
|
|
#define UPGRADE_TBL_SQL_CMD ("CREATE TABLE IF NOT EXISTS %supgrade (" \
|
|
"ID INTEGER PRIMARY KEY AUTOINCREMENT," \
|
|
"keyName TEXT NOT NULL," \
|
|
"resType INTEGER NOT NULL," \
|
|
"priority INTEGER NOT NULL DEFAULT (1)," \
|
|
"resVersion TEXT NOT NULL," \
|
|
"localPath TEXT NOT NULL," \
|
|
"serverURL TEXT NOT NULL," \
|
|
"md5Chksum TEXT NOT NULL," \
|
|
"resReadme TEXT NOT NULL DEFAULT (\'\')," \
|
|
"resStatus INTEGER NOT NULL DEFAULT (1)," \
|
|
"dlId TEXT NOT NULL DEFAULT (\'\')," \
|
|
"dlStatus INTEGER NOT NULL DEFAULT (0)," \
|
|
"dlRetrys INTEGER NOT NULL DEFAULT (0)," \
|
|
"dlTime TimeStamp NOT NULL DEFAULT (datetime('now','localtime')));")
|
|
|
|
#define CREATE_TMP_TBL_SQL "CREATE TABLE IF NOT EXISTS %stmp (" \
|
|
"ID INTEGER PRIMARY KEY AUTOINCREMENT," \
|
|
"localPath TEXT NOT NULL);"
|
|
|
|
static int g_isDlFinished = FALSE;
|
|
static unsigned int g_curDlItems = 0;
|
|
static sqlite3* g_pMemDb = NULL;
|
|
static uv_rwlock_t g_uvSkinRwLock;
|
|
static uv_rwlock_t g_uvDlRwLock;
|
|
static const unsigned int g_tolDefaultSkins = (sizeof(g_SkinDefaultResTable) / sizeof(g_SkinDefaultResTable[0]));
|
|
static PSKINS_CACHE_ITEM g_pSkinCackeTbl = NULL;
|
|
|
|
char* TblGetSkinsResource(char *pKeyName, int *pResType, int *pVersion, char **pComeFrom);
|
|
static int __getUpgradeInfo(const char *pUpdFilePath);
|
|
static int __reTryDlSkinResCb(void *pData, int argc, char **argv, char **azColName);
|
|
extern int InitSkinRomDatabase(sqlite3 *pDataBase);
|
|
static int g_isVerifyRes = FALSE;
|
|
static int g_isUpgradeRunning = FALSE;
|
|
|
|
static int __dumpSkinsInfo(PSKIN_RES_INFO pItem, int nItems)
|
|
{
|
|
LOG_EX2(LOG_Debug, "Skins Items Information:\n");
|
|
|
|
LOG_EX2(LOG_Debug, "-------------------------------------------------------------"
|
|
"--------------------------------------------------------\n");
|
|
|
|
LOG_EX2(LOG_Debug, "| Key Name | Type | MD5 Checksum |"
|
|
" Contexts "
|
|
" |\n");
|
|
|
|
LOG_EX2(LOG_Debug, "-------------------------------------------------------------"
|
|
"--------------------------------------------------------\n");
|
|
|
|
for(int i = 0; i < nItems && pItem; i++, pItem++)
|
|
{
|
|
LOG_EX2(LOG_Debug, "| %-8s | %-8s | %-32s | %-80s |\n",
|
|
pItem->pKeyName, pItem->pResVer, pItem->pMD5Chksum, pItem->pLocalPath);
|
|
}
|
|
|
|
LOG_EX2(LOG_Debug, "-------------------------------------------------------------"
|
|
"--------------------------------------------------------\n");
|
|
}
|
|
|
|
static int __verifyResMD5Chksum(const char* pPath, const char* pChksum, int resType)
|
|
{
|
|
const char* pMD5Chksum;
|
|
|
|
if(resType == TEXT_RES)
|
|
{
|
|
return (TRUE);
|
|
}
|
|
|
|
if(pPath == NULL || pChksum == NULL)
|
|
{
|
|
return (FALSE);
|
|
}
|
|
|
|
switch(resType)
|
|
{
|
|
case IMAGE_RES:
|
|
case VOICE_RES:
|
|
pMD5Chksum = EvpMD5HashFile(pPath);
|
|
|
|
if(pMD5Chksum == NULL)
|
|
{
|
|
return (FALSE);
|
|
}
|
|
|
|
if(strcmp(pMD5Chksum, pChksum) != 0)
|
|
{
|
|
LOG_EX(LOG_Error, "%s MD5 Verify Error: %s -> %s\n", pPath, pMD5Chksum, pChksum);
|
|
|
|
free((char*)pMD5Chksum);
|
|
return (FALSE);
|
|
}
|
|
else
|
|
{
|
|
free((char*)pMD5Chksum);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
return (FALSE);
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
static void __checkRes(sqlite3_context *pContext, int argc, sqlite3_value **argv)
|
|
{
|
|
if(access(sqlite3_value_text(argv[0]), F_OK) != 0)
|
|
{
|
|
sqlite3_result_int(pContext, -1);
|
|
}
|
|
else if(__verifyResMD5Chksum(sqlite3_value_text(argv[0]),
|
|
sqlite3_value_text(argv[1]),
|
|
sqlite3_value_int(argv[2])) == FALSE)
|
|
{
|
|
sqlite3_result_int(pContext, -2);
|
|
}
|
|
else
|
|
{
|
|
sqlite3_result_int(pContext, 0);
|
|
}
|
|
}
|
|
|
|
static int __cleanupSkinTbl(void)
|
|
{
|
|
int rc;
|
|
char* pErrMsg = NULL;
|
|
UT_string* pSqlCmd = NULL;
|
|
|
|
utstring_new(pSqlCmd);
|
|
utstring_printf(pSqlCmd, "DROP TABLE %s.%s", SKIN_USER_DB, SKIN_TBL_NAME);
|
|
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Delete Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
utstring_free(pSqlCmd);
|
|
return -ERR_SQLITE3_CREATE_TABLE;
|
|
}
|
|
|
|
utstring_renew(pSqlCmd);
|
|
utstring_printf(pSqlCmd, CREATE_SKIN_TBL_SQL, SKIN_USER_DB".");
|
|
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
utstring_free(pSqlCmd);
|
|
return -ERR_SQLITE3_CREATE_TABLE;
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
return 0;
|
|
}
|
|
|
|
static int __cleanupResTbl(void)
|
|
{
|
|
int rc;
|
|
char* pErrMsg = NULL;
|
|
UT_string* pSqlCmd = NULL;
|
|
|
|
utstring_new(pSqlCmd);
|
|
utstring_printf(pSqlCmd, "DROP TABLE %s.%s", SKIN_USER_DB, RES_TBL_NAME);
|
|
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Delete Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
utstring_free(pSqlCmd);
|
|
return -ERR_SQLITE3_CREATE_TABLE;
|
|
}
|
|
|
|
utstring_renew(pSqlCmd);
|
|
utstring_printf(pSqlCmd, CREATE_RES_TBL_SQL, SKIN_USER_DB".");
|
|
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
utstring_free(pSqlCmd);
|
|
return -ERR_SQLITE3_CREATE_TABLE;
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
return 0;
|
|
}
|
|
|
|
static int __cleanupUpgTbl(void)
|
|
{
|
|
int rc;
|
|
char* pErrMsg = NULL;
|
|
UT_string* pSqlCmd = NULL;
|
|
|
|
utstring_new(pSqlCmd);
|
|
utstring_printf(pSqlCmd, "DROP TABLE %s.upgrade", SKIN_USER_DB);
|
|
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Delete Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
utstring_free(pSqlCmd);
|
|
return -ERR_SQLITE3_CREATE_TABLE;
|
|
}
|
|
|
|
utstring_renew(pSqlCmd);
|
|
utstring_printf(pSqlCmd, UPGRADE_TBL_SQL_CMD, SKIN_USER_DB".");
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
utstring_free(pSqlCmd);
|
|
return -ERR_SQLITE3_CREATE_TABLE;
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
return 0;
|
|
}
|
|
|
|
static int __cleanupTmpTbl(void)
|
|
{
|
|
int rc;
|
|
char* pErrMsg = NULL;
|
|
UT_string* pSqlCmd = NULL;
|
|
|
|
utstring_new(pSqlCmd);
|
|
utstring_printf(pSqlCmd, "DROP TABLE main.tmp");
|
|
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Delete Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
utstring_free(pSqlCmd);
|
|
return -ERR_SQLITE3_CREATE_TABLE;
|
|
}
|
|
|
|
utstring_renew(pSqlCmd);
|
|
utstring_printf(pSqlCmd, CREATE_TMP_TBL_SQL, "main.");
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
utstring_free(pSqlCmd);
|
|
return -ERR_SQLITE3_CREATE_TABLE;
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
return 0;
|
|
}
|
|
|
|
static int __skinCreateCfgDB(void)
|
|
{
|
|
int rc = 0;
|
|
char* pErrMsg = NULL;
|
|
UT_string *pSqlCmd = NULL;
|
|
|
|
utstring_new(pSqlCmd);
|
|
utstring_printf(pSqlCmd, "CREATE VIRTUAL TABLE main.%s USING %s;"
|
|
"CREATE VIRTUAL TABLE main.%s USING %s;",
|
|
SKIN_TBL_NAME, SKIN_MODE_NAME, RES_TBL_NAME, RES_MODE_NAME);
|
|
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
utstring_free(pSqlCmd);
|
|
return -ERR_SQLITE3_CREATE_TABLE;
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
|
|
return (0);
|
|
}
|
|
|
|
static int __skinCreateCfgFile(const char* pCfgFilePath)
|
|
{
|
|
char* pErrMsg = NULL;
|
|
int rc = 0;
|
|
static sqlite3* pSqlFileDB = NULL;
|
|
UT_string *pSqlCmd = NULL;
|
|
|
|
rc = sqlite3_open(":memory:", &g_pMemDb);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "sqlite3_open memory: %s\n", pCfgFilePath);
|
|
return -ERR_OPEN_SQLITE3_DB;
|
|
}
|
|
|
|
utstring_new(pSqlCmd);
|
|
utstring_printf(pSqlCmd, CREATE_TMP_TBL_SQL, "");
|
|
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
unlink(pCfgFilePath);
|
|
sqlite3_close(g_pMemDb);
|
|
utstring_free(pSqlCmd);
|
|
return -ERR_SQLITE3_CREATE_TABLE;
|
|
}
|
|
|
|
rc = sqlite3_open_v2(pCfgFilePath, &pSqlFileDB, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "sqlite3_open_v2 error: %s\n", pCfgFilePath);
|
|
sqlite3_close(g_pMemDb);
|
|
utstring_free(pSqlCmd);
|
|
return -ERR_OPEN_SQLITE3_DB;
|
|
}
|
|
|
|
utstring_renew(pSqlCmd);
|
|
utstring_printf(pSqlCmd, CREATE_SKIN_TBL_SQL""CREATE_RES_TBL_SQL, "", "");
|
|
|
|
rc = sqlite3_exec(pSqlFileDB, utstring_body(pSqlCmd), NULL, 0, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
unlink(pCfgFilePath);
|
|
sqlite3_close(g_pMemDb);
|
|
utstring_free(pSqlCmd);
|
|
return -ERR_SQLITE3_CREATE_TABLE;
|
|
}
|
|
|
|
utstring_renew(pSqlCmd);
|
|
utstring_printf(pSqlCmd, UPGRADE_TBL_SQL_CMD, "");
|
|
rc = sqlite3_exec(pSqlFileDB, utstring_body(pSqlCmd), NULL, 0, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", UPGRADE_TBL_SQL_CMD, pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
unlink(pCfgFilePath);
|
|
sqlite3_close(g_pMemDb);
|
|
utstring_free(pSqlCmd);
|
|
return -ERR_SQLITE3_CREATE_TABLE;
|
|
}
|
|
|
|
sqlite3_close(pSqlFileDB);
|
|
|
|
utstring_renew(pSqlCmd);
|
|
utstring_printf(pSqlCmd, ATTACH_DB_SQL_CMD, pCfgFilePath, SKIN_USER_DB);
|
|
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Attach Database %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
utstring_free(pSqlCmd);
|
|
sqlite3_free(pErrMsg);
|
|
unlink(pCfgFilePath);
|
|
sqlite3_close(g_pMemDb);
|
|
return -ERR_SQLITE3_CREATE_TABLE;
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
|
|
rc = sqlite3_create_function(g_pMemDb, "ResCheck", 3, SQLITE_UTF8, NULL, __checkRes, NULL, NULL);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Don't Support Resurces Verify Function\n");
|
|
}
|
|
|
|
if(InitSkinRomDatabase(g_pMemDb) != 0)
|
|
{
|
|
sqlite3_close(g_pMemDb);
|
|
return (-ERR_SQL_REG_MODULE);
|
|
}
|
|
|
|
rc = __skinCreateCfgDB();
|
|
|
|
if(rc != 0)
|
|
{
|
|
sqlite3_close(g_pMemDb);
|
|
return rc;
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
static void __onDlFileCb(void *pData, unsigned int size,
|
|
const char *pReqUrl, const char* pDlPath,
|
|
const char *pTaskUuid, int iFinished, void *pUserData)
|
|
{
|
|
char* pId = (char*)pUserData;
|
|
UT_string *pSqlCmd = NULL;
|
|
int rc = 0;
|
|
char* pErrMsg = NULL;
|
|
|
|
if(g_curDlItems > 0)
|
|
{
|
|
g_curDlItems--;
|
|
}
|
|
|
|
if(iFinished == 0 && pId != NULL)
|
|
{
|
|
//LOG_EX(LOG_Debug, "Request(%s): [%s] --> [%s] Response: [%u] OK\n", pTaskUuid, pReqUrl, pDlPath, size);
|
|
|
|
utstring_new(pSqlCmd);
|
|
utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET dlStatus = %d, dlRetrys = %d, "
|
|
"dlTime = datetime(\'now\', \'localtime\') WHERE ID = %s AND "
|
|
"ResCheck(localPath, md5Chksum, resType) = 0",
|
|
SKIN_USER_DB, STATUS_DOWNLOADED, 0, pId);
|
|
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "SQL Query Error: %s\n", pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
}
|
|
else
|
|
{
|
|
if(iFinished == 1)
|
|
{
|
|
LOG_EX(LOG_Error, "Request(%s): [%s] --> [%s] Response: [%u] Error\n", pTaskUuid, pReqUrl, pDlPath, size);
|
|
}
|
|
else
|
|
{
|
|
LOG_EX(LOG_Error, "Download %s Error: %d\n", pReqUrl, iFinished);
|
|
}
|
|
|
|
utstring_new(pSqlCmd);
|
|
utstring_printf(pSqlCmd, "SELECT * FROM %s.upgrade WHERE ID = %s AND dlRetrys < 5 ", SKIN_USER_DB, pId);
|
|
|
|
//fprintf(stdout, "SQL:\n%s\n", utstring_body(pSqlCmd));
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __reTryDlSkinResCb, NULL, &pErrMsg);
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "SQL %s Query Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
}
|
|
|
|
if(pId)
|
|
{
|
|
free(pId);
|
|
}
|
|
}
|
|
|
|
static int __reTryDlSkinResCb(void *pData, int argc, char **argv, char **azColName)
|
|
{
|
|
UT_string *pSqlCmd = NULL;
|
|
char* pErrMsg = NULL;
|
|
|
|
const char* pDlTaskId = InetHttpDlFileAsync(argv[6],
|
|
argv[5],
|
|
__onDlFileCb,
|
|
NULL,
|
|
strdup(argv[0]));
|
|
|
|
if(pDlTaskId != NULL)
|
|
{
|
|
int rc = 0;
|
|
|
|
utstring_new(pSqlCmd);
|
|
utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET dlId = \'%s\', dlRetrys = dlRetrys + 1, "
|
|
"dlTime = datetime(\'now\', \'localtime\') WHERE ID = %s",
|
|
SKIN_USER_DB, pDlTaskId, argv[0]);
|
|
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "SQL Query Error: %s\n", pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int __loadDownloadSkinsCb(void *pData, int argc, char **argv, char **azColName)
|
|
{
|
|
const char *pDlTaskId;
|
|
char* pItemId = argv[0];
|
|
char* pURL = argv[6];
|
|
char* pDlPath = argv[5];
|
|
char* pDlId = argv[10];
|
|
int dlStatus = strtol(argv[3], NULL, 10);
|
|
int dlRetry = strtol(argv[4], NULL, 10) + 1;
|
|
|
|
if(dlStatus == STATUS_DOWNLOADING)
|
|
{
|
|
if(strlen(pDlId) > 0)
|
|
{
|
|
InetCancelDownload(pDlId);
|
|
}
|
|
|
|
dlRetry++;
|
|
}
|
|
|
|
//LOG_EX(LOG_Debug, "Download: %s --> %s\n", pURL, pDlPath);
|
|
|
|
pDlTaskId = InetHttpDlFileAsync(pURL,
|
|
pDlPath,
|
|
__onDlFileCb,
|
|
NULL,
|
|
strdup(pItemId));
|
|
|
|
if(pDlTaskId)
|
|
{
|
|
UT_string *pSqlCmd = NULL;
|
|
int rc = 0;
|
|
char* pErrMsg = NULL;
|
|
|
|
g_curDlItems++;
|
|
|
|
utstring_new(pSqlCmd);
|
|
utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET dlStatus = %d, dlRetrys = %d, "
|
|
"dlId = \'%s\', dlTime = datetime(\'now\', \'localtime\') WHERE ID = %s",
|
|
SKIN_USER_DB, STATUS_DOWNLOADING, dlRetry, pDlTaskId, pItemId);
|
|
#if DEBUG_SQL_CMD
|
|
LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd));
|
|
#endif
|
|
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "SQL Query Error: %s\n", pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
}
|
|
else
|
|
{
|
|
LOG_EX(LOG_Error, "Download %s error\n", pURL);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
static void __uvDownloadResThread(void *pParams)
|
|
{
|
|
char* pErrMsg = NULL;
|
|
UT_string* pSqlCmd = NULL;
|
|
|
|
LOG_EX(LOG_Debug, "Beging Download Skins\n");
|
|
|
|
while(!g_isDlFinished)
|
|
{
|
|
int rc = 0;
|
|
|
|
utstring_new(pSqlCmd);
|
|
utstring_printf(pSqlCmd, "SELECT *, STRFTIME(\"%%s\", datetime(\'now\', \'localtime\')) "
|
|
"- STRFTIME(\"%%s\", upgrade.dlTime) AS diff FROM %s.upgrade "
|
|
"WHERE resStatus = %d AND (dlRetrys < 5 OR diff > 600) "
|
|
"AND (dlStatus = %d OR (dlStatus = %d AND diff > 600)) "
|
|
"LIMIT 10 - %d",
|
|
SKIN_USER_DB, UPG_STATUS_DL_NEW, STATUS_CREATE_NEW, STATUS_DOWNLOADING, g_curDlItems);
|
|
#if DEBUG_SQL_CMD
|
|
LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd));
|
|
#endif
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __loadDownloadSkinsCb, NULL, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "SQL Query Error: %s\n", pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
|
|
sleep(1);
|
|
}
|
|
|
|
LOG_EX(LOG_Debug, "Download Skins Finished\n");
|
|
|
|
pthread_detach(pthread_self());
|
|
}
|
|
|
|
static int __sqlCbRemoveUnusedFile(void *pData, int argc, char **argv, char **azColName)
|
|
{
|
|
LOG_EX(LOG_Debug, "Clean up resources: [%s]\n", argv[1]);
|
|
|
|
if(access(argv[1], F_OK) == 0
|
|
&& strncmp(argv[1], DEF_SKINS_ROOT_PATH, strlen(DEF_SKINS_ROOT_PATH)) != 0)
|
|
{
|
|
unlink(argv[1]);
|
|
}
|
|
}
|
|
|
|
static int __createResTblCb(void *pData, int argc, char **argv, char **azColName)
|
|
{
|
|
int rc = 0;
|
|
char* pErrMsg = NULL;
|
|
UT_string* pSqlCmd = NULL;
|
|
|
|
//DEBUG_SQL_CALLBACK_DATA(argc, argv, azColName);
|
|
|
|
utstring_new(pSqlCmd);
|
|
utstring_printf(pSqlCmd, "INSERT INTO %s.%s "
|
|
"VALUES (NULL, \'%s\', \'%s\', \'%s\', \'%s\')",
|
|
SKIN_USER_DB, RES_TBL_NAME, argv[0], argv[1], argv[2], argv[3]);
|
|
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "[%s] Query Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
utstring_free(pSqlCmd);
|
|
return -1;
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int __createSkinTblCb(void *pData, int argc, char **argv, char **azColName)
|
|
{
|
|
int rc = 0;
|
|
char* pErrMsg = NULL;
|
|
UT_string* pSqlCmd = NULL;
|
|
|
|
//DEBUG_SQL_CALLBACK_DATA(argc, argv, azColName);
|
|
|
|
utstring_renew(pSqlCmd);
|
|
utstring_printf(pSqlCmd, "INSERT INTO %s.%s "
|
|
"VALUES (NULL, \'%s\', %s, %s, %s, \'%s\')",
|
|
SKIN_USER_DB, SKIN_TBL_NAME,
|
|
argv[1], argv[2], argv[3], argv[0], argv[4]);
|
|
|
|
//fprintf(stdout, "AutoId: %lld: %s\n", sqlite3_last_insert_rowid(g_pMemDb), argv[3]);
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "[%s] Query Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
return -1;
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
return 0;
|
|
}
|
|
|
|
static void __uvSyncResThread(void *pParams)
|
|
{
|
|
int tolCnt = 0;
|
|
PSKINS_CACHE_ITEM pItem = NULL, pTemp = NULL;
|
|
|
|
LOG_EX(LOG_Debug, "Beging Sync Download Skins\n");
|
|
|
|
while(TRUE)
|
|
{
|
|
UT_string *pSqlCmd = NULL;
|
|
int rc = 0;
|
|
char* pErrMsg = NULL;
|
|
char **pResult = NULL;
|
|
int iRow = 0, iCol = 0;
|
|
int nItems = 0;
|
|
|
|
utstring_new(pSqlCmd);
|
|
utstring_printf(pSqlCmd, "SELECT COUNT(*) FROM %s.upgrade "
|
|
"WHERE resStatus = %d AND dlStatus != %d",
|
|
SKIN_USER_DB, UPG_STATUS_DL_NEW, STATUS_DOWNLOADED);
|
|
#if DEBUG_SQL_CMD
|
|
LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd));
|
|
#endif
|
|
rc = sqlite3_get_table(g_pMemDb, utstring_body(pSqlCmd), &pResult, &iRow, &iCol, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
|
|
nItems = strtol(pResult[1], NULL, 10);
|
|
sqlite3_free_table(pResult);
|
|
|
|
if(tolCnt++ % 20 == 0)
|
|
{
|
|
LOG_EX(LOG_Debug, "Download: Remain %d\n", nItems);
|
|
}
|
|
|
|
if(nItems == 0)
|
|
{
|
|
g_isDlFinished = TRUE;
|
|
utstring_new(pSqlCmd);
|
|
sqlite3_exec(g_pMemDb, "BEGIN TRANSACTION;", NULL, NULL, NULL);
|
|
|
|
utstring_printf(pSqlCmd, "INSERT INTO main.tmp "
|
|
"SELECT %s.ID, %s.localPath FROM %s.%s "
|
|
"LEFT JOIN %s.upgrade on %s.md5Chksum = upgrade.md5Chksum "
|
|
"WHERE upgrade.md5Chksum IS NULL;",
|
|
RES_TBL_NAME, RES_TBL_NAME, SKIN_USER_DB, RES_TBL_NAME,
|
|
SKIN_USER_DB, RES_TBL_NAME);
|
|
#if DEBUG_SQL_CMD
|
|
LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd));
|
|
#endif
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL);
|
|
utstring_free(pSqlCmd);
|
|
break;
|
|
}
|
|
|
|
__cleanupSkinTbl();
|
|
__cleanupResTbl();
|
|
|
|
utstring_renew(pSqlCmd);
|
|
|
|
utstring_printf(pSqlCmd, "SELECT resVersion, localPath, serverURL, md5Chksum, "
|
|
"keyName, resType, priority, resReadme, resStatus, dlStatus "
|
|
"FROM %s.upgrade WHERE resStatus = %d "
|
|
"OR (resStatus = %d AND dlStatus = %d) "
|
|
"GROUP BY md5Chksum",
|
|
SKIN_USER_DB, UPG_STATUS_DOWNLOADED,
|
|
UPG_STATUS_DL_NEW, STATUS_DOWNLOADED);
|
|
#if DEBUG_SQL_CMD
|
|
LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd));
|
|
#endif
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __createResTblCb, NULL, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL);
|
|
utstring_free(pSqlCmd);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
utstring_renew(pSqlCmd);
|
|
utstring_printf(pSqlCmd, "SELECT %s.ID, keyName, resType, priority, "
|
|
"resReadme, resStatus, dlStatus, %s.md5Chksum "
|
|
"FROM %s.upgrade, %s.res WHERE %s.md5Chksum = upgrade.md5Chksum"
|
|
" AND (resStatus = %d OR (resStatus = %d AND dlStatus = %d)) "
|
|
"ORDER BY keyName",
|
|
RES_TBL_NAME, RES_TBL_NAME, SKIN_USER_DB, SKIN_USER_DB, RES_TBL_NAME,
|
|
UPG_STATUS_DOWNLOADED, UPG_STATUS_DL_NEW, STATUS_DOWNLOADED);
|
|
#if DEBUG_SQL_CMD
|
|
LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd));
|
|
#endif
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __createSkinTblCb, NULL, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL);
|
|
utstring_free(pSqlCmd);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
sqlite3_exec(g_pMemDb, "SELECT * FROM main.tmp", __sqlCbRemoveUnusedFile, NULL, NULL);
|
|
utstring_free(pSqlCmd);
|
|
|
|
if(__cleanupUpgTbl() != 0)
|
|
{
|
|
sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL);
|
|
}
|
|
else
|
|
{
|
|
sqlite3_exec(g_pMemDb, "END TRANSACTION;", NULL, NULL, NULL);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
sleep(1);
|
|
}
|
|
|
|
LOG_EX(LOG_Debug, "Sync Download Skins Finished\n");
|
|
|
|
uv_rwlock_wrlock(&g_SkinCacheRwLock);
|
|
HASH_ITER(hh, g_pSkinCackeTbl, pItem, pTemp)
|
|
{
|
|
free(pItem->pKeyName);
|
|
free(pItem->pResPath);
|
|
free(pItem);
|
|
pItem = NULL;
|
|
}
|
|
|
|
g_pSkinCackeTbl = NULL;
|
|
uv_rwlock_wrunlock(&g_SkinCacheRwLock);
|
|
|
|
g_isUpgradeRunning = FALSE;
|
|
pthread_detach(pthread_self());
|
|
}
|
|
|
|
static int __upgStatusTblCb(void *pData, int argc, char **argv, char **azColName)
|
|
{
|
|
int rc = 0;
|
|
char* pErrMsg = NULL;
|
|
UT_string* pSqlCmd = NULL;
|
|
|
|
DEBUG_SQL_CALLBACK_DATA(argc, argv, azColName);
|
|
|
|
utstring_new(pSqlCmd);
|
|
utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET resStatus = %d WHERE ID = %s",
|
|
SKIN_USER_DB, UPG_STATUS_DL_NEW, argv[2]);
|
|
|
|
rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "[%s] Query Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
utstring_free(pSqlCmd);
|
|
return -1;
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int __saveUpgradeInfo(PSKIN_RES_INFO pInfo, int nItems)
|
|
{
|
|
int isError = FALSE;
|
|
char* pErrMsg = NULL;
|
|
UT_string* pSqlCmd = NULL;
|
|
|
|
if(pInfo == NULL || nItems <= 0)
|
|
{
|
|
return (-ERR_INPUT_PARAMS);
|
|
}
|
|
|
|
utstring_new(pSqlCmd);
|
|
|
|
sqlite3_exec(g_pMemDb, "BEGIN TRANSACTION;", NULL, NULL, NULL);
|
|
__cleanupUpgTbl();
|
|
__cleanupTmpTbl();
|
|
|
|
for(int i = 0; i < nItems; i++)
|
|
{
|
|
UT_string* pPath = NULL;
|
|
PSKIN_RES_INFO pItem = &pInfo[i];
|
|
|
|
utstring_new(pPath);
|
|
utstring_renew(pSqlCmd);
|
|
|
|
#if 0
|
|
if(pItem->resType == VOICE_RES)
|
|
{
|
|
utstring_printf(pPath, "%svoice/%s", DOWNLOAD_RES_ROOT_PATH, basename_v2(pItem->pLocalPath));
|
|
}
|
|
|
|
else if(pItem->resType == IMAGE_RES)
|
|
{
|
|
utstring_printf(pPath, "%simage/%s", DOWNLOAD_RES_ROOT_PATH, basename_v2(pItem->pLocalPath));
|
|
}
|
|
else if(pItem->resType == TEXT_RES)
|
|
{
|
|
utstring_printf(pPath, "%s", pItem->pLocalPath);
|
|
}
|
|
else
|
|
{
|
|
utstring_free(pPath);
|
|
continue;
|
|
}
|
|
#else
|
|
utstring_printf(pPath, "%svoice/%s", DOWNLOAD_RES_ROOT_PATH, basename_v2(pItem->pLocalPath));
|
|
#endif
|
|
utstring_printf(pSqlCmd, "INSERT INTO %s.upgrade (keyName, resType, resVersion, localPath, serverURL, md5Chksum)"
|
|
" SELECT \'%s\', %d, \'%s\', \'%s\', \'%s\', \'%s\' ",
|
|
SKIN_USER_DB, pItem->pKeyName, pItem->resType, pItem->pResVer, utstring_body(pPath),
|
|
pItem->pLocalPath, pItem->pMD5Chksum);
|
|
|
|
#if DEBUG_SQL_CMD
|
|
LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd));
|
|
#endif
|
|
|
|
if((sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg) != SQLITE_OK))
|
|
{
|
|
LOG_EX(LOG_Error, "Add Skins[%d] %s To Database Error: %s\n", i, pItem->pKeyName, utstring_body(pSqlCmd));
|
|
LOG_EX(LOG_Error, "SQL Error: %s\n", pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
isError = TRUE;
|
|
utstring_free(pPath);
|
|
break;
|
|
}
|
|
|
|
utstring_free(pPath);
|
|
}
|
|
|
|
utstring_renew(pSqlCmd);
|
|
|
|
utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET resStatus = %d "
|
|
"WHERE EXISTS (SELECT %s.keyName, upgrade.md5Chksum FROM main.%s, user_db.upgrade "
|
|
"WHERE upgrade.keyName = %s.keyName)",
|
|
SKIN_USER_DB, UPG_STATUS_DL_NEW,
|
|
SKIN_TBL_NAME, SKIN_TBL_NAME,
|
|
SKIN_TBL_NAME);
|
|
|
|
#if DEBUG_SQL_CMD
|
|
LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd));
|
|
#endif
|
|
|
|
if(sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __upgStatusTblCb, 0, &pErrMsg) != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Upgrade Status: %s\n", utstring_body(pSqlCmd));
|
|
LOG_EX(LOG_Error, "SQL Error: %s\n", pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
isError = TRUE;
|
|
}
|
|
|
|
utstring_renew(pSqlCmd);
|
|
|
|
utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET resStatus = %d "
|
|
"WHERE EXISTS (SELECT %s.md5Chksum FROM %s.%s "
|
|
"WHERE upgrade.md5Chksum = %s.md5Chksum);"
|
|
"UPDATE %s.upgrade SET resStatus = %d, localPath = "
|
|
"(SELECT %s.localPath FROM main.%s "
|
|
"WHERE upgrade.md5Chksum = %s.md5Chksum) "
|
|
"WHERE EXISTS (SELECT %s.md5Chksum FROM main.%s "
|
|
"WHERE upgrade.md5Chksum = %s.md5Chksum);",
|
|
SKIN_USER_DB, UPG_STATUS_DOWNLOADED,
|
|
RES_TBL_NAME, SKIN_USER_DB, RES_TBL_NAME,
|
|
RES_TBL_NAME,
|
|
SKIN_USER_DB, UPG_STATUS_DOWNLOADED,
|
|
RES_TBL_NAME, RES_TBL_NAME, RES_TBL_NAME,
|
|
RES_TBL_NAME, RES_TBL_NAME, RES_TBL_NAME);
|
|
|
|
#if DEBUG_SQL_CMD
|
|
LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd));
|
|
#endif
|
|
|
|
if(sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg) != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Upgrade Status: %s\n", utstring_body(pSqlCmd));
|
|
LOG_EX(LOG_Error, "SQL Error: %s\n", pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
isError = TRUE;
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
|
|
|
|
if(isError == TRUE)
|
|
{
|
|
sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL);
|
|
return (-ERR_SQL_QUERY);
|
|
}
|
|
else
|
|
{
|
|
uv_thread_t uvSyncThread, uvDlThread;
|
|
sqlite3_exec(g_pMemDb, "END TRANSACTION;", NULL, NULL, NULL);
|
|
g_curDlItems = 0;
|
|
g_isDlFinished = FALSE;
|
|
uv_thread_create(&uvDlThread, __uvDownloadResThread, NULL);
|
|
uv_thread_create(&uvSyncThread, __uvSyncResThread, NULL);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int __loadPreUpgradeInfo(void)
|
|
{
|
|
UT_string *pSqlCmd = NULL;
|
|
int rc = 0;
|
|
char* pErrMsg = NULL;
|
|
char **pResult = NULL;
|
|
int iRow = 0, iCol = 0;
|
|
int nItems = 0;
|
|
|
|
utstring_new(pSqlCmd);
|
|
utstring_printf(pSqlCmd, "SELECT COUNT(*) FROM %s.upgrade WHERE resStatus = %d AND dlStatus != %d",
|
|
SKIN_USER_DB, UPG_STATUS_DL_NEW, STATUS_DOWNLOADED);
|
|
|
|
rc = sqlite3_get_table(g_pMemDb, utstring_body(pSqlCmd), &pResult, &iRow, &iCol, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s\n", utstring_body(pSqlCmd), pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
|
|
nItems = strtol(pResult[1], NULL, 10);
|
|
sqlite3_free_table(pResult);
|
|
|
|
if(nItems > 0)
|
|
{
|
|
uv_thread_t uvSyncThread, uvDlThread;
|
|
g_curDlItems = 0;
|
|
g_isDlFinished = FALSE;
|
|
g_isUpgradeRunning = TRUE;
|
|
uv_thread_create(&uvDlThread, __uvDownloadResThread, NULL);
|
|
uv_thread_create(&uvSyncThread, __uvSyncResThread, NULL);
|
|
LOG_EX(LOG_Debug, "Load Pre Download Items: %d\n", nItems);
|
|
}
|
|
}
|
|
|
|
static int __getEnumResInfo(void)
|
|
{
|
|
__saveUpgradeInfo((PSKIN_RES_INFO)g_emuUpgradeInfo, sizeof(g_emuUpgradeInfo) / sizeof(g_emuUpgradeInfo[0]));
|
|
}
|
|
|
|
int SkinUpgrade(char* pUpdData)
|
|
{
|
|
int nItems = 0;
|
|
PSKIN_RES_INFO pUpgResInfo;
|
|
cJSON *pRoot, *pList;
|
|
|
|
#if 1
|
|
FILE *pFile = fopen("/mnt/UDISK/skinupgrade.txt", "w+");
|
|
fwrite(pUpdData, 1, strlen(pUpdData), pFile);
|
|
fclose(pFile);
|
|
#endif
|
|
|
|
if (pUpdData == NULL || strlen(pUpdData) == 0)
|
|
{
|
|
LOG_EX(LOG_Error, "Input Params Error\n");
|
|
return (-ERR_INPUT_PARAMS);
|
|
}
|
|
|
|
LOG_EX(LOG_Debug, "Upgrade Cmd: [%s]\n", pUpdData);
|
|
//fprintf(stdout, "%s\n", pUpdData);
|
|
|
|
pRoot = cJSON_Parse(pUpdData);
|
|
|
|
if(pRoot == NULL)
|
|
{
|
|
LOG_EX(LOG_Error, "Parse Json Error\n");
|
|
return (-ERR_NO_ITEMS);
|
|
}
|
|
|
|
nItems = cJSON_GetArraySize(pRoot);
|
|
|
|
if(nItems <= 0)
|
|
{
|
|
LOG_EX(LOG_Error, "Upgrade Item: %d\n", nItems);
|
|
cJSON_Delete(pRoot);
|
|
return (-ERR_NO_ITEMS);
|
|
}
|
|
|
|
pUpgResInfo = (PSKIN_RES_INFO)malloc(sizeof(SKIN_RES_INFO) * nItems);
|
|
|
|
if(pUpgResInfo == NULL)
|
|
{
|
|
LOG_EX(LOG_Error, "Malloc %d Memory Error\n", nItems);
|
|
cJSON_Delete(pRoot);
|
|
return (-ERR_MALLOC_MEMORY);
|
|
}
|
|
|
|
LOG_EX(LOG_Debug, "Array Size = %d\n", nItems);
|
|
|
|
memset(pUpgResInfo, 0, sizeof(SKIN_RES_INFO) * nItems);
|
|
pList = pRoot->child;
|
|
|
|
for(int i = 0; i < nItems; i++)
|
|
{
|
|
pUpgResInfo[i].resType = VOICE_RES;//cJSON_GetObjectItem(pList, "resourceType")->valueint;
|
|
pUpgResInfo[i].pResVer = strdup(cJSON_GetObjectItem(pList, "resourceVersion")->valuestring);
|
|
pUpgResInfo[i].pKeyName = strdup(cJSON_GetObjectItem(pList, "resourceName")->valuestring);
|
|
pUpgResInfo[i].pLocalPath = strdup(cJSON_GetObjectItem(pList, "url")->valuestring);
|
|
pUpgResInfo[i].pMD5Chksum = strdup(cJSON_GetObjectItem(pList, "md5")->valuestring);
|
|
|
|
pList = pList->next;
|
|
}
|
|
|
|
cJSON_Delete(pRoot);
|
|
|
|
g_isUpgradeRunning = TRUE;
|
|
__dumpSkinsInfo(pUpgResInfo, nItems);
|
|
__saveUpgradeInfo(pUpgResInfo, nItems);
|
|
|
|
free(pUpgResInfo);
|
|
}
|
|
|
|
char* SQLiteGetSkinsResource(char *pKeyName, int *pResType, int *pVersion, char **pComeFrom)
|
|
{
|
|
char *pSkinPath = strdup("");
|
|
int rc = 0;
|
|
char* pErrMsg = NULL;
|
|
UT_string *pSqlCmd = NULL;
|
|
char **pResult = NULL;
|
|
int iRow = 0, iCol = 0;
|
|
int queCol = 13;
|
|
int colPath = 21;
|
|
|
|
utstring_new(pSqlCmd);
|
|
|
|
if(g_isVerifyRes)
|
|
{
|
|
utstring_printf(pSqlCmd, "SELECT *, RANDOM() AS rnd, ResCheck(localPath, md5Chksum, resType) as resOK "
|
|
"FROM %s.%s, %s.%s\n"
|
|
"WHERE %s.keyName = \'%s\' AND resOK = 0 AND %s.resId = %s.ID\n"
|
|
"UNION\n"
|
|
"SELECT *, RANDOM() AS rnd, ResCheck(localPath, md5Chksum, resType) as resOK "
|
|
"FROM main.%s, main.%s\n"
|
|
"WHERE %s.keyName = \'%s\' AND resOK = 0 AND %s.resId = %s.ID\n"
|
|
"ORDER BY priority DESC, rnd "
|
|
"LIMIT 1",
|
|
SKIN_USER_DB, SKIN_TBL_NAME, SKIN_USER_DB, RES_TBL_NAME,
|
|
SKIN_TBL_NAME, pKeyName, SKIN_TBL_NAME, RES_TBL_NAME,
|
|
SKIN_TBL_NAME, RES_TBL_NAME,
|
|
SKIN_TBL_NAME, pKeyName, SKIN_TBL_NAME, RES_TBL_NAME);
|
|
}
|
|
else
|
|
{
|
|
utstring_printf(pSqlCmd, "SELECT *, RANDOM() AS rnd "
|
|
"FROM %s.%s, %s.%s\n"
|
|
"WHERE %s.keyName = \'%s\' AND %s.resId = %s.ID\n"
|
|
"UNION\n"
|
|
"SELECT *, RANDOM() AS rnd "
|
|
"FROM main.%s, main.%s\n"
|
|
"WHERE %s.keyName = \'%s\' AND %s.resId = %s.ID\n"
|
|
"ORDER BY priority DESC, rnd "
|
|
"LIMIT 1",
|
|
SKIN_USER_DB, SKIN_TBL_NAME, SKIN_USER_DB, RES_TBL_NAME,
|
|
SKIN_TBL_NAME, pKeyName, SKIN_TBL_NAME, RES_TBL_NAME,
|
|
SKIN_TBL_NAME, RES_TBL_NAME,
|
|
SKIN_TBL_NAME, pKeyName, SKIN_TBL_NAME, RES_TBL_NAME);
|
|
queCol = 12;
|
|
colPath = 20;
|
|
}
|
|
|
|
rc = sqlite3_get_table(g_pMemDb, utstring_body(pSqlCmd), &pResult, &iRow, &iCol, &pErrMsg);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s(%d)\n", utstring_body(pSqlCmd), pErrMsg, rc);
|
|
sqlite3_free(pErrMsg);
|
|
utstring_free(pSqlCmd);
|
|
return (pSkinPath);
|
|
}
|
|
|
|
if(iRow == 1 && iCol == queCol)
|
|
{
|
|
|
|
if(access(pResult[colPath], F_OK) != 0)
|
|
{
|
|
LOG_EX(LOG_Error, "Res %s --> %s not exists\n", pKeyName, pResult[colPath]);
|
|
}
|
|
else
|
|
{
|
|
free(pSkinPath);
|
|
pSkinPath = strdup(pResult[colPath]);
|
|
}
|
|
#if 0
|
|
for(int i = 0; i <= 21; i++)
|
|
{
|
|
LOG_EX(LOG_Debug, "[%d]: {%s}\n", i, pResult[i]);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#if 0
|
|
int index = iCol;
|
|
for(int i = 0; i < iRow; i++)
|
|
{
|
|
fprintf(stdout, "----------%d[%d, %d]---------\n", i, iRow, iCol);
|
|
|
|
for(int j = 0; j < iCol; j++)
|
|
{
|
|
int tblCol = i * iCol + j;
|
|
|
|
fprintf(stdout, "%s(%d, %d) = [%s]\n", pResult[tblCol], j, index, pResult[index]);
|
|
index++;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
sqlite3_free_table(pResult);
|
|
utstring_free(pSqlCmd);
|
|
|
|
if(strcmp(pSkinPath, "") == 0)
|
|
{
|
|
free(pSkinPath);
|
|
return TblGetSkinsResource(pKeyName, pResType, pVersion, pComeFrom);
|
|
}
|
|
else
|
|
{
|
|
return (pSkinPath);
|
|
}
|
|
}
|
|
|
|
char* TblGetSkinsResource(char *pKeyName, int *pResType, int *pVersion, char **pComeFrom)
|
|
{
|
|
|
|
for(int i = 0; i < sizeof(g_SkinDefaultResTable) / sizeof(g_SkinDefaultResTable[0]); i++)
|
|
{
|
|
if(strcmp(g_SkinDefaultResTable[i].pKeyName, pKeyName) == 0)
|
|
{
|
|
return strdup(g_SkinDefaultResTable[i].pLocalPath);
|
|
}
|
|
}
|
|
|
|
return strdup("");
|
|
}
|
|
|
|
char* GetSkinsResource(char *pKeyName, int *pResType, int *pVersion, char **pComeFrom)
|
|
{
|
|
if(g_isUpgradeRunning)
|
|
{
|
|
return TblGetSkinsResource(pKeyName, pResType, pVersion, pComeFrom);
|
|
}
|
|
else
|
|
{
|
|
return SQLiteGetSkinsResource(pKeyName, pResType, pVersion, pComeFrom);
|
|
}
|
|
}
|
|
|
|
unsigned int SkinsDefaultSize(void)
|
|
{
|
|
return (g_tolDefaultSkins + 1);
|
|
}
|
|
|
|
PSKIN_RES_INFO SkinsItemById(int iId)
|
|
{
|
|
if(iId < 0 || iId > g_tolDefaultSkins)
|
|
{
|
|
return (NULL);
|
|
}
|
|
|
|
return ((PSKIN_RES_INFO)&g_SkinDefaultResTable[iId - 1]);
|
|
}
|
|
|
|
static int __verifyResValuableCb(void *pData, int argc, char **argv, char **azColName)
|
|
{
|
|
char sqlCmd[256];
|
|
char* pErrMsg = NULL;
|
|
|
|
if(argc < 3)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
sqlite3_exec(g_pMemDb, "BEGIN TRANSACTION;", NULL, NULL, NULL);
|
|
for(int i = 0; i < argc; i++)
|
|
{
|
|
if(strcmp(azColName[i], "ID") == 0)
|
|
{
|
|
LOG_EX(LOG_Error, "Cleanup Bad Resources: %s\n", argv[i + 1]);
|
|
|
|
memset(sqlCmd, 0, 256);
|
|
sprintf(sqlCmd, "DELETE FROM %s.%s WHERE ID = %s", SKIN_USER_DB, RES_TBL_NAME, argv[i]);
|
|
|
|
if(sqlite3_exec(g_pMemDb, sqlCmd, __verifyResValuableCb, 0, &pErrMsg) != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "SQL: %s\nError: %s\n", sqlCmd, pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL);
|
|
return -1;
|
|
}
|
|
|
|
unlink(argv[i + 1]);
|
|
}
|
|
}
|
|
sqlite3_exec(g_pMemDb, "END TRANSACTION;", NULL, NULL, NULL);
|
|
|
|
return (0);
|
|
}
|
|
|
|
static void VerifySkinResInfo(void)
|
|
{
|
|
UT_string *pSqlCmd = NULL;
|
|
char* pErrMsg = NULL;
|
|
|
|
utstring_new(pSqlCmd);
|
|
utstring_printf(pSqlCmd, "SELECT ID, localPath, md5Chksum FROM %s.%s "
|
|
"WHERE ResCheck(localPath, md5Chksum, 1) != 0", SKIN_USER_DB, RES_TBL_NAME);
|
|
|
|
if(sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __verifyResValuableCb, 0, &pErrMsg) != SQLITE_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "SQL Error: %s\n", pErrMsg);
|
|
sqlite3_free(pErrMsg);
|
|
utstring_free(pSqlCmd);
|
|
return;
|
|
}
|
|
|
|
utstring_free(pSqlCmd);
|
|
}
|
|
|
|
void SkinIsVerifyRes(int isVerify)
|
|
{
|
|
g_isVerifyRes = isVerify;
|
|
}
|
|
|
|
int SkinInit(void)
|
|
{
|
|
int rc = 0;
|
|
UT_string* pPath = NULL;
|
|
#if 0
|
|
int tmUsed = 0;
|
|
struct timeval tmStart, tmEnd;
|
|
|
|
if(DBusLibuvGetRuntime() == NULL)
|
|
{
|
|
int ret = 0;
|
|
uv_thread_t uvThread;
|
|
LOG_EX(LOG_Warn, "+++++++++++++++++++++++System Uninit\n");
|
|
|
|
DBusConnection* pBus = DBusWithLibuvInit(GetDBusDefaultLoop(),
|
|
g_pModInfoTable[MODULE_SKINS].modAliase,
|
|
__dusOnMsg,
|
|
NULL,
|
|
NULL, //KeyEventCb,
|
|
&ret);
|
|
|
|
if(pBus == NULL)
|
|
{
|
|
LOG_EX(LOG_Error, "DBusWithLibuvInit Error: %d\n", ret);
|
|
return -ERR_UNINIT_ITEM;
|
|
}
|
|
|
|
uv_thread_create(&uvThread, uvLoopProc, NULL);
|
|
}
|
|
#endif
|
|
|
|
uv_rwlock_init(&g_uvSkinRwLock);
|
|
uv_rwlock_init(&g_uvDlRwLock);
|
|
uv_rwlock_init(&g_SkinCacheRwLock);
|
|
|
|
utstring_new(pPath);
|
|
|
|
utstring_printf(pPath, "mkdir -p %s/image > /dev/zero", DOWNLOAD_RES_ROOT_PATH);
|
|
rc = system(utstring_body(pPath));
|
|
|
|
utstring_renew(pPath);
|
|
utstring_printf(pPath, "mkdir -p %s/voice > /dev/zero", DOWNLOAD_RES_ROOT_PATH);
|
|
rc = system(utstring_body(pPath));
|
|
|
|
utstring_free(pPath);
|
|
|
|
rc = __skinCreateCfgFile(SKINS_DB_PATH);
|
|
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
return rc;
|
|
}
|
|
|
|
// gettimeofday(&tmStart, NULL);
|
|
VerifySkinResInfo();
|
|
// gettimeofday(&tmEnd, NULL);
|
|
|
|
// tmUsed = (tmEnd.tv_sec * 1000000 + tmEnd.tv_usec) - (tmStart.tv_sec * 1000000 + tmStart.tv_usec);
|
|
// LOG_EX(LOG_Debug, "VerifySkinResInfo used time: %d(us)\n", tmUsed);
|
|
|
|
__loadPreUpgradeInfo();
|
|
//__getEnumResInfo();
|
|
//__getUpgradeInfo("./hotfix.txt");
|
|
//__loadDownloadItems();
|
|
|
|
//__dumpSkinsInfo();
|
|
}
|