1416 lines
30 KiB
C++
1416 lines
30 KiB
C++
#include "WebUser.h"
|
||
#include "WebServer.h"
|
||
#include "base/HGInfo.h"
|
||
#include "base/HGBase64.h"
|
||
#include "base/HGImage.h"
|
||
#include "imgfmt/HGJpeg.h"
|
||
#include "sha1.h"
|
||
#include "base64.h"
|
||
#include "HGString.h"
|
||
|
||
static int GetJsonIntValue(cJSON* json, const std::string& key, bool* find = NULL)
|
||
{
|
||
int ret = 0;
|
||
if (NULL != find)
|
||
*find = false;
|
||
|
||
cJSON* p = json->child;
|
||
while (NULL != p)
|
||
{
|
||
if (0 == strcmp(p->string, key.c_str()))
|
||
{
|
||
if (p->type == cJSON_Number)
|
||
{
|
||
ret = p->valueint;
|
||
if (NULL != find)
|
||
*find = true;
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
p = p->next;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
static double GetJsonDoubleValue(cJSON* json, const std::string& key, bool* find = NULL)
|
||
{
|
||
double ret = 0.0;
|
||
if (NULL != find)
|
||
*find = false;
|
||
|
||
cJSON* p = json->child;
|
||
while (NULL != p)
|
||
{
|
||
if (0 == strcmp(p->string, key.c_str()))
|
||
{
|
||
if (p->type == cJSON_Number)
|
||
{
|
||
ret = p->valuedouble;
|
||
if (NULL != find)
|
||
*find = true;
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
p = p->next;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
static bool GetJsonBoolValue(cJSON* json, const std::string& key, bool* find = NULL)
|
||
{
|
||
bool ret = false;
|
||
if (NULL != find)
|
||
*find = false;
|
||
|
||
cJSON* p = json->child;
|
||
while (NULL != p)
|
||
{
|
||
if (0 == strcmp(p->string, key.c_str()))
|
||
{
|
||
if (p->type == cJSON_True || p->type == cJSON_False)
|
||
{
|
||
ret = (p->type == cJSON_True) ? true : false;
|
||
if (NULL != find)
|
||
*find = true;
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
p = p->next;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
static std::string GetJsonStringValue(cJSON* json, const std::string& key, bool* find = NULL)
|
||
{
|
||
std::string ret;
|
||
if (NULL != find)
|
||
*find = false;
|
||
|
||
cJSON* p = json->child;
|
||
while (NULL != p)
|
||
{
|
||
if (0 == strcmp(p->string, key.c_str()))
|
||
{
|
||
if (p->type == cJSON_String)
|
||
{
|
||
ret = p->valuestring;
|
||
if (NULL != find)
|
||
*find = true;
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
p = p->next;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
static std::vector<std::string> GetJsonStringListValue(cJSON* json, const std::string& key, bool* find = NULL)
|
||
{
|
||
std::vector<std::string> ret;
|
||
if (NULL != find)
|
||
*find = false;
|
||
|
||
cJSON* p = json->child;
|
||
while (NULL != p)
|
||
{
|
||
if (0 == strcmp(p->string, key.c_str()))
|
||
{
|
||
if (p->type == cJSON_Array)
|
||
{
|
||
cJSON* pEx = p->child;
|
||
while (NULL != pEx)
|
||
{
|
||
if (pEx->type == cJSON_String)
|
||
ret.push_back(pEx->valuestring);
|
||
|
||
pEx = pEx->next;
|
||
}
|
||
|
||
if (NULL != find)
|
||
*find = true;
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
p = p->next;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
static std::vector<int> GetJsonIntListValue(cJSON* json, const std::string& key, bool* find = NULL)
|
||
{
|
||
std::vector<int> ret;
|
||
if (NULL != find)
|
||
*find = false;
|
||
|
||
cJSON* p = json->child;
|
||
while (NULL != p)
|
||
{
|
||
if (0 == strcmp(p->string, key.c_str()))
|
||
{
|
||
if (p->type == cJSON_Array)
|
||
{
|
||
cJSON* pEx = p->child;
|
||
while (NULL != pEx)
|
||
{
|
||
if (pEx->type == cJSON_Number)
|
||
ret.push_back(pEx->valueint);
|
||
|
||
pEx = pEx->next;
|
||
}
|
||
|
||
if (NULL != find)
|
||
*find = true;
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
p = p->next;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
|
||
#if defined(HG_CMP_MSC)
|
||
WebUser::WebUser(WebServer* server, HGUInt id, HGMsgPump msgPump, const std::string& ip, uint16_t port, SOCKET sockConn)
|
||
#else
|
||
WebUser::WebUser(WebServer* server, HGUInt id, HGMsgPump msgPump, const std::string& ip, uint16_t port, int sockConn)
|
||
#endif
|
||
{
|
||
m_lock = NULL;
|
||
HGBase_CreateLock(&m_lock);
|
||
m_lockName = NULL;
|
||
HGBase_CreateLock(&m_lockName);
|
||
m_server = server;
|
||
m_id = id;
|
||
m_msgPump = msgPump;
|
||
m_ip = ip;
|
||
m_port = port;
|
||
m_sockConn = sockConn;
|
||
|
||
m_thread = NULL;
|
||
HGBase_OpenThread(ThreadFunc, this, &m_thread);
|
||
assert(NULL != m_thread);
|
||
|
||
m_jpgQuality = 80;
|
||
m_devNameList.clear();
|
||
m_devName.clear();
|
||
m_devHandle = NULL;
|
||
m_dpi = 0;
|
||
m_scanEvent = NULL;
|
||
|
||
SANE_Int version_code = 0;
|
||
sane_init_ex(&version_code, sane_ex_callback, this);
|
||
}
|
||
|
||
WebUser::~WebUser()
|
||
{
|
||
if (NULL != m_scanEvent)
|
||
{
|
||
assert(NULL != m_devHandle);
|
||
sane_cancel(m_devHandle);
|
||
|
||
HGBase_WaitEvent(m_scanEvent);
|
||
HGBase_DestroyEvent(m_scanEvent);
|
||
m_scanEvent = NULL;
|
||
}
|
||
|
||
if (NULL != m_devHandle)
|
||
{
|
||
m_dpi = 0;
|
||
sane_close(m_devHandle);
|
||
m_devHandle = NULL;
|
||
m_devName.clear();
|
||
}
|
||
|
||
sane_exit();
|
||
|
||
#if defined(HG_CMP_MSC)
|
||
closesocket(m_sockConn);
|
||
m_sockConn = INVALID_SOCKET;
|
||
#else
|
||
close(m_sockConn);
|
||
m_sockConn = -1;
|
||
#endif
|
||
HGBase_CloseThread(m_thread);
|
||
m_thread = NULL;
|
||
|
||
m_port = 0;
|
||
m_ip.clear();
|
||
m_msgPump = NULL;
|
||
m_id = 0;
|
||
m_server = NULL;
|
||
HGBase_DestroyLock(m_lockName);
|
||
m_lockName = NULL;
|
||
HGBase_DestroyLock(m_lock);
|
||
m_lock = NULL;
|
||
}
|
||
|
||
HGUInt WebUser::GetId()
|
||
{
|
||
return m_id;
|
||
}
|
||
|
||
void WebUser::CloseDev(const CloseDevParam* param)
|
||
{
|
||
assert(NULL != param && m_id == param->usrId);
|
||
|
||
if (m_devName == param->devName)
|
||
{
|
||
if (NULL != m_scanEvent)
|
||
{
|
||
assert(NULL != m_devHandle);
|
||
sane_cancel(m_devHandle);
|
||
|
||
HGBase_WaitEvent(m_scanEvent);
|
||
HGBase_DestroyEvent(m_scanEvent);
|
||
m_scanEvent = NULL;
|
||
}
|
||
|
||
if (NULL != m_devHandle)
|
||
{
|
||
m_dpi = 0;
|
||
sane_close(m_devHandle);
|
||
m_devHandle = NULL;
|
||
m_devName.clear();
|
||
}
|
||
}
|
||
}
|
||
|
||
void WebUser::ScanFinish(const ScanFinishParam* param)
|
||
{
|
||
assert(NULL != param && m_id == param->usrId);
|
||
|
||
if (NULL != m_scanEvent)
|
||
{
|
||
assert(NULL != m_devHandle);
|
||
sane_cancel(m_devHandle);
|
||
|
||
HGBase_WaitEvent(m_scanEvent);
|
||
HGBase_DestroyEvent(m_scanEvent);
|
||
m_scanEvent = NULL;
|
||
}
|
||
}
|
||
|
||
void WebUser::HandleCmd(const WSCmdParam* param)
|
||
{
|
||
assert(NULL != param && m_id == param->usrId);
|
||
|
||
std::string cmdData((const char*)param->data, param->size);
|
||
cJSON* json = cJSON_Parse(cmdData.c_str());
|
||
if (NULL != json)
|
||
{
|
||
std::string func = GetJsonStringValue(json, "Func");
|
||
if ("GetDeviceList" == func)
|
||
{
|
||
GetDeviceList(json);
|
||
}
|
||
else if ("SelectDevice" == func)
|
||
{
|
||
SelectDevice(json);
|
||
}
|
||
else if ("SetScanColorType" == func)
|
||
{
|
||
SetScanColorType(json);
|
||
}
|
||
else if ("SetDPI" == func)
|
||
{
|
||
SetDPI(json);
|
||
}
|
||
else if ("SetDuplex" == func)
|
||
{
|
||
SetDuplex(json);
|
||
}
|
||
else if ("SetScanJPGQuality" == func)
|
||
{
|
||
SetScanJPGQuality(json);
|
||
}
|
||
else if ("StartScan" == func)
|
||
{
|
||
StartScan(json);
|
||
}
|
||
|
||
cJSON_Delete(json);
|
||
}
|
||
}
|
||
|
||
void WebUser::HandleEvent(const WSEvtParam* param)
|
||
{
|
||
assert(NULL != param && m_id == param->usrId);
|
||
|
||
SendResponse(param->data, param->size, HGTRUE);
|
||
}
|
||
|
||
void WebUser::GetDeviceList(cJSON* json)
|
||
{
|
||
assert(NULL != json);
|
||
|
||
cJSON* retJson = cJSON_CreateObject();
|
||
if (NULL != retJson)
|
||
{
|
||
cJSON_AddItemToObject(retJson, "Func", cJSON_CreateString("GetDeviceList"));
|
||
cJSON_AddItemToObject(retJson, "code", cJSON_CreateString("0"));
|
||
|
||
cJSON* array = cJSON_CreateArray();
|
||
cJSON_AddItemToObject(retJson, "result", array);
|
||
|
||
HGBase_EnterLock(m_lockName);
|
||
for (int i = 0; i < (int)m_devNameList.size(); ++i)
|
||
{
|
||
cJSON* js = cJSON_CreateObject();
|
||
char str[10] = {0};
|
||
sprintf(str, "%d", i);
|
||
cJSON_AddItemToObject(js, "index", cJSON_CreateString(str));
|
||
cJSON_AddItemToObject(js, "name", cJSON_CreateString(m_devNameList[i].c_str()));
|
||
cJSON_AddItemToArray(array, js);
|
||
}
|
||
HGBase_LeaveLock(m_lockName);
|
||
|
||
char* resp = cJSON_Print(retJson);
|
||
if (NULL != resp)
|
||
{
|
||
SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE);
|
||
free(resp);
|
||
}
|
||
|
||
cJSON_Delete(retJson);
|
||
}
|
||
}
|
||
|
||
void WebUser::SelectDevice(cJSON* json)
|
||
{
|
||
assert(NULL != json);
|
||
|
||
int code = -1;
|
||
std::string result = "错误";
|
||
|
||
int index = atoi(GetJsonStringValue(json, "arg").c_str());
|
||
|
||
HGBase_EnterLock(m_lockName);
|
||
if (index >= 0 && index < (int)m_devNameList.size())
|
||
{
|
||
if (m_devNameList[index] == m_devName)
|
||
{
|
||
code = 0;
|
||
result.clear();
|
||
}
|
||
else
|
||
{
|
||
if (NULL != m_scanEvent)
|
||
{
|
||
assert(NULL != m_devHandle);
|
||
sane_cancel(m_devHandle);
|
||
|
||
HGBase_WaitEvent(m_scanEvent);
|
||
HGBase_DestroyEvent(m_scanEvent);
|
||
m_scanEvent = NULL;
|
||
}
|
||
|
||
if (NULL != m_devHandle)
|
||
{
|
||
m_dpi = 0;
|
||
sane_close(m_devHandle);
|
||
m_devHandle = NULL;
|
||
m_devName.clear();
|
||
}
|
||
|
||
SANE_Handle dev = NULL;
|
||
SANE_Status status = sane_open(m_devNameList[index].c_str(), &dev);
|
||
if (SANE_STATUS_GOOD == status)
|
||
{
|
||
m_devName = m_devNameList[index];
|
||
m_devHandle = dev;
|
||
m_dpi = GetDpi();
|
||
code = 0;
|
||
result.clear();
|
||
}
|
||
}
|
||
}
|
||
HGBase_LeaveLock(m_lockName);
|
||
|
||
cJSON* retJson = cJSON_CreateObject();
|
||
if (NULL != retJson)
|
||
{
|
||
cJSON_AddItemToObject(retJson, "Func", cJSON_CreateString("SelectDevice"));
|
||
char str[10] = { 0 };
|
||
sprintf(str, "%d", code);
|
||
cJSON_AddItemToObject(retJson, "code", cJSON_CreateString(str));
|
||
cJSON_AddItemToObject(retJson, "result", cJSON_CreateString(StdStringToUtf8(result).c_str()));
|
||
|
||
char* resp = cJSON_Print(retJson);
|
||
if (NULL != resp)
|
||
{
|
||
SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE);
|
||
free(resp);
|
||
}
|
||
|
||
cJSON_Delete(retJson);
|
||
}
|
||
}
|
||
|
||
void WebUser::SetScanColorType(cJSON* json)
|
||
{
|
||
assert(NULL != json);
|
||
|
||
int code = -1;
|
||
std::string result = "错误";
|
||
|
||
int colorMode = atoi(GetJsonStringValue(json, "arg").c_str());
|
||
|
||
if (NULL != m_devHandle && NULL == m_scanEvent && colorMode >= 1 && colorMode <= 3)
|
||
{
|
||
const char* colorModeStr = OPTION_VALUE_YSMS_24WCS;
|
||
if (2 == colorMode)
|
||
colorModeStr = OPTION_VALUE_YSMS_256JHD;
|
||
else if (3 == colorMode)
|
||
colorModeStr = OPTION_VALUE_YSMS_HB;
|
||
|
||
if (SetParam(OPTION_TITLE_YSMS, colorModeStr))
|
||
{
|
||
code = 0;
|
||
result.clear();
|
||
}
|
||
}
|
||
|
||
cJSON* retJson = cJSON_CreateObject();
|
||
if (NULL != retJson)
|
||
{
|
||
cJSON_AddItemToObject(retJson, "Func", cJSON_CreateString("SetScanColorType"));
|
||
char str[10] = { 0 };
|
||
sprintf(str, "%d", code);
|
||
cJSON_AddItemToObject(retJson, "code", cJSON_CreateString(str));
|
||
cJSON_AddItemToObject(retJson, "result", cJSON_CreateString(StdStringToUtf8(result).c_str()));
|
||
|
||
char* resp = cJSON_Print(retJson);
|
||
if (NULL != resp)
|
||
{
|
||
SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE);
|
||
free(resp);
|
||
}
|
||
|
||
cJSON_Delete(retJson);
|
||
}
|
||
}
|
||
|
||
void WebUser::SetDPI(cJSON* json)
|
||
{
|
||
assert(NULL != json);
|
||
|
||
int code = -1;
|
||
std::string result = "错误";
|
||
|
||
int dpi = atoi(GetJsonStringValue(json, "arg").c_str());
|
||
|
||
if (NULL != m_devHandle && NULL == m_scanEvent && dpi > 0)
|
||
{
|
||
if (SetParam(OPTION_TITLE_FBL, &dpi))
|
||
{
|
||
m_dpi = dpi;
|
||
code = 0;
|
||
result.clear();
|
||
}
|
||
}
|
||
|
||
cJSON* retJson = cJSON_CreateObject();
|
||
if (NULL != retJson)
|
||
{
|
||
cJSON_AddItemToObject(retJson, "Func", cJSON_CreateString("SetDPI"));
|
||
char str[10] = { 0 };
|
||
sprintf(str, "%d", code);
|
||
cJSON_AddItemToObject(retJson, "code", cJSON_CreateString(str));
|
||
cJSON_AddItemToObject(retJson, "result", cJSON_CreateString(StdStringToUtf8(result).c_str()));
|
||
|
||
char* resp = cJSON_Print(retJson);
|
||
if (NULL != resp)
|
||
{
|
||
SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE);
|
||
free(resp);
|
||
}
|
||
|
||
cJSON_Delete(retJson);
|
||
}
|
||
}
|
||
|
||
void WebUser::SetDuplex(cJSON* json)
|
||
{
|
||
assert(NULL != json);
|
||
|
||
int code = -1;
|
||
std::string result = "错误";
|
||
|
||
int duplexMode = atoi(GetJsonStringValue(json, "arg").c_str());
|
||
|
||
if (NULL != m_devHandle && NULL == m_scanEvent && duplexMode >= 0 && duplexMode <= 1)
|
||
{
|
||
const char* duplexModeStr = OPTION_VALUE_SMYM_DM;
|
||
if (1 == duplexMode)
|
||
duplexModeStr = OPTION_VALUE_SMYM_SM;
|
||
|
||
if (SetParam(OPTION_TITLE_SMYM, duplexModeStr))
|
||
{
|
||
code = 0;
|
||
result.clear();
|
||
}
|
||
}
|
||
|
||
cJSON* retJson = cJSON_CreateObject();
|
||
if (NULL != retJson)
|
||
{
|
||
cJSON_AddItemToObject(retJson, "Func", cJSON_CreateString("SetDuplex"));
|
||
char str[10] = { 0 };
|
||
sprintf(str, "%d", code);
|
||
cJSON_AddItemToObject(retJson, "code", cJSON_CreateString(str));
|
||
cJSON_AddItemToObject(retJson, "result", cJSON_CreateString(StdStringToUtf8(result).c_str()));
|
||
|
||
char* resp = cJSON_Print(retJson);
|
||
if (NULL != resp)
|
||
{
|
||
SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE);
|
||
free(resp);
|
||
}
|
||
|
||
cJSON_Delete(retJson);
|
||
}
|
||
}
|
||
|
||
void WebUser::SetScanJPGQuality(cJSON* json)
|
||
{
|
||
assert(NULL != json);
|
||
|
||
int code = -1;
|
||
std::string result = "错误";
|
||
|
||
int jpegQuality = atoi(GetJsonStringValue(json, "arg").c_str());
|
||
|
||
if (NULL == m_scanEvent && jpegQuality >= 0 && jpegQuality <= 100)
|
||
{
|
||
m_jpgQuality = jpegQuality;
|
||
code = 0;
|
||
result.clear();
|
||
}
|
||
|
||
cJSON* retJson = cJSON_CreateObject();
|
||
if (NULL != retJson)
|
||
{
|
||
cJSON_AddItemToObject(retJson, "Func", cJSON_CreateString("SetScanJPGQuality"));
|
||
char str[10] = { 0 };
|
||
sprintf(str, "%d", code);
|
||
cJSON_AddItemToObject(retJson, "code", cJSON_CreateString(str));
|
||
cJSON_AddItemToObject(retJson, "result", cJSON_CreateString(StdStringToUtf8(result).c_str()));
|
||
|
||
char* resp = cJSON_Print(retJson);
|
||
if (NULL != resp)
|
||
{
|
||
SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE);
|
||
free(resp);
|
||
}
|
||
|
||
cJSON_Delete(retJson);
|
||
}
|
||
}
|
||
|
||
void WebUser::StartScan(cJSON* json)
|
||
{
|
||
assert(NULL != json);
|
||
|
||
int code = -1;
|
||
std::string result = "错误";
|
||
|
||
int scanPage = atoi(GetJsonStringValue(json, "arg").c_str());
|
||
|
||
if (NULL != m_devHandle && NULL == m_scanEvent && scanPage >= 0)
|
||
{
|
||
if (0 == scanPage)
|
||
{
|
||
SetParam(OPTION_TITLE_SMZS, OPTION_VALUE_SMZS_LXSM);
|
||
}
|
||
else
|
||
{
|
||
SetParam(OPTION_TITLE_SMZS, OPTION_VALUE_SMZS_SMZDZS);
|
||
SetParam(OPTION_TITLE_SMSL, &scanPage);
|
||
}
|
||
|
||
HGBase_CreateEvent(HGFALSE, HGFALSE, &m_scanEvent);
|
||
assert(NULL != m_scanEvent);
|
||
|
||
SANE_Status status = sane_start(m_devHandle);
|
||
if (SANE_STATUS_GOOD == status)
|
||
{
|
||
code = 0;
|
||
result.clear();
|
||
}
|
||
else
|
||
{
|
||
HGBase_DestroyEvent(m_scanEvent);
|
||
m_scanEvent = NULL;
|
||
}
|
||
}
|
||
|
||
cJSON* retJson = cJSON_CreateObject();
|
||
if (NULL != retJson)
|
||
{
|
||
cJSON_AddItemToObject(retJson, "Func", cJSON_CreateString("StartScan"));
|
||
char str[10] = { 0 };
|
||
sprintf(str, "%d", code);
|
||
cJSON_AddItemToObject(retJson, "code", cJSON_CreateString(str));
|
||
cJSON_AddItemToObject(retJson, "result", cJSON_CreateString(StdStringToUtf8(result).c_str()));
|
||
|
||
char* resp = cJSON_Print(retJson);
|
||
if (NULL != resp)
|
||
{
|
||
SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE);
|
||
free(resp);
|
||
}
|
||
|
||
cJSON_Delete(retJson);
|
||
}
|
||
}
|
||
|
||
void WebUser::PostDisConnectMsg()
|
||
{
|
||
DisConnectParam* param = new DisConnectParam;
|
||
param->svr = m_server;
|
||
param->usrId = m_id;
|
||
|
||
HGMsg msg;
|
||
msg.id = MSGID_DISCONNECT;
|
||
msg.data = param;
|
||
if (HGBASE_ERR_OK != HGBase_PostPumpMessage(m_msgPump, &msg))
|
||
{
|
||
delete param;
|
||
}
|
||
}
|
||
|
||
void WebUser::PostCmdMsg(const HGByte* data, HGUInt dataSize)
|
||
{
|
||
WSCmdParam* param = new WSCmdParam;
|
||
param->svr = m_server;
|
||
param->usrId = m_id;
|
||
param->data = new HGByte[dataSize];
|
||
param->size = dataSize;
|
||
memcpy(param->data, data, dataSize);
|
||
|
||
HGMsg msg;
|
||
msg.id = MSGID_WS_COMMAND;
|
||
msg.data = param;
|
||
if (HGBASE_ERR_OK != HGBase_PostPumpMessage(m_msgPump, &msg))
|
||
{
|
||
delete[] param->data;
|
||
param->size = 0;
|
||
delete param;
|
||
}
|
||
}
|
||
|
||
void WebUser::PostEventMsg(const HGByte* data, HGUInt dataSize)
|
||
{
|
||
WSEvtParam* param = new WSEvtParam;
|
||
param->svr = m_server;
|
||
param->usrId = m_id;
|
||
param->data = new HGByte[dataSize];
|
||
param->size = dataSize;
|
||
memcpy(param->data, data, dataSize);
|
||
|
||
HGMsg msg;
|
||
msg.id = MSGID_WS_EVENT;
|
||
msg.data = param;
|
||
if (HGBASE_ERR_OK != HGBase_PostPumpMessage(m_msgPump, &msg))
|
||
{
|
||
delete[] param->data;
|
||
param->size = 0;
|
||
delete param;
|
||
}
|
||
}
|
||
|
||
void HGAPI WebUser::ThreadFunc(HGThread thread, HGPointer param)
|
||
{
|
||
WebUser* p = (WebUser*)param;
|
||
|
||
char chBuffer[2048];
|
||
const char* pBuffer = chBuffer;
|
||
int nBufferSize = 0;
|
||
bool bConnect = false;
|
||
|
||
unsigned char connectDataTail[4] = { '\r', '\n', '\r', '\n' };
|
||
unsigned int connectDataTailLen = 0;
|
||
std::string connectData;
|
||
|
||
uint8_t* pData = NULL;
|
||
int nDataSize = 0;
|
||
uint8_t* pDataEx = NULL;
|
||
int nRemainSize = 0;
|
||
uint8_t headData[20];
|
||
uint32_t nHeadDataLen = 0;
|
||
uint8_t vMask[4];
|
||
uint32_t nMaskCount = 0;
|
||
bool bHandle = false;
|
||
std::vector<uint8_t> vAllData;
|
||
|
||
while (1)
|
||
{
|
||
if (0 == nBufferSize)
|
||
{
|
||
int len = recv(p->m_sockConn, chBuffer, 2048, 0);
|
||
if (len <= 0)
|
||
{
|
||
// 这里跳出,可能是服务器关闭了socketConn,或者客户端关闭了socket,或者网络断开
|
||
p->PostDisConnectMsg();
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
pBuffer = chBuffer;
|
||
nBufferSize = len;
|
||
}
|
||
}
|
||
|
||
assert(nBufferSize > 0);
|
||
|
||
if (!bConnect)
|
||
{
|
||
unsigned char b = *pBuffer;
|
||
++pBuffer;
|
||
--nBufferSize;
|
||
|
||
connectData.push_back(b);
|
||
if (b == connectDataTail[connectDataTailLen])
|
||
{
|
||
++connectDataTailLen;
|
||
}
|
||
else
|
||
{
|
||
connectDataTailLen = 0;
|
||
if (b == connectDataTail[connectDataTailLen])
|
||
{
|
||
++connectDataTailLen;
|
||
}
|
||
}
|
||
|
||
if (4 == connectDataTailLen)
|
||
{
|
||
connectDataTailLen = 0;
|
||
bool shakeRet = p->ShakeHand(connectData);
|
||
connectData.clear();
|
||
|
||
if (!shakeRet)
|
||
{
|
||
p->PostDisConnectMsg();
|
||
break;
|
||
}
|
||
|
||
bConnect = true;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (NULL == pData)
|
||
{
|
||
assert(0 == nDataSize);
|
||
|
||
uint8_t b = *pBuffer;
|
||
++pBuffer;
|
||
--nBufferSize;
|
||
headData[nHeadDataLen] = b;
|
||
++nHeadDataLen;
|
||
|
||
if (1 == nHeadDataLen)
|
||
{
|
||
if ((0x80 | 0x08) == headData[0]) // 断开连接
|
||
{
|
||
p->PostDisConnectMsg();
|
||
break;
|
||
}
|
||
else if ((0x80 | 0x09) == headData[0]) // PING帧
|
||
{
|
||
//
|
||
}
|
||
else if ((0x80 | 0x0A) == headData[0]) // PONG帧
|
||
{
|
||
//
|
||
}
|
||
else if ((0x00 | 0x01) == headData[0] || (0x00 | 0x02) == headData[0] || (0x00 | 0x00) == headData[0] || (0x80 | 0x00) == headData[0]
|
||
|| (0x80 | 0x01) == headData[0] || (0x80 | 0x02) == headData[0]) // 数据帧
|
||
{
|
||
if ((0x80 | 0x00) == headData[0] || (0x80 | 0x01) == headData[0] || (0x80 | 0x02) == headData[0])
|
||
{
|
||
// 分片结束
|
||
bHandle = true;
|
||
}
|
||
else
|
||
{
|
||
// 分片帧
|
||
bHandle = false;
|
||
}
|
||
}
|
||
else // 帧错误,断开连接
|
||
{
|
||
p->PostDisConnectMsg();
|
||
break;
|
||
}
|
||
}
|
||
else if (2 == nHeadDataLen)
|
||
{
|
||
if (0 == (headData[1] & 0x80)) // 必须经过掩码处理
|
||
{
|
||
p->PostDisConnectMsg();
|
||
break;
|
||
}
|
||
|
||
if ((0x80 | 0x09) == headData[0]) // PING帧
|
||
{
|
||
if (0x80 != headData[1])
|
||
{
|
||
p->PostDisConnectMsg();
|
||
break;
|
||
}
|
||
}
|
||
else if ((0x80 | 0x0A) == headData[0]) // PONG帧
|
||
{
|
||
if (0x80 != headData[1])
|
||
{
|
||
p->PostDisConnectMsg();
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ((headData[1] & 0x7F) <= 125)
|
||
{
|
||
uint32_t nCmdSize = (headData[1] & 0x7F);
|
||
nHeadDataLen = 0;
|
||
|
||
if (0 == nCmdSize)
|
||
{
|
||
p->PostDisConnectMsg();
|
||
break;
|
||
}
|
||
|
||
nDataSize = nCmdSize;
|
||
nRemainSize = nCmdSize;
|
||
pData = new uint8_t[nDataSize];
|
||
pDataEx = pData;
|
||
}
|
||
}
|
||
}
|
||
else if (4 == nHeadDataLen)
|
||
{
|
||
if ((0x80 | 0x09) == headData[0]) // PING帧
|
||
{
|
||
//
|
||
}
|
||
else if ((0x80 | 0x0A) == headData[0]) // PONG帧
|
||
{
|
||
//
|
||
}
|
||
else
|
||
{
|
||
if ((headData[1] & 0x7F) == 126)
|
||
{
|
||
uint32_t nCmdSize = ntohs(*(uint16_t*)&headData[2]);
|
||
nHeadDataLen = 0;
|
||
|
||
if (0 == nCmdSize)
|
||
{
|
||
p->PostDisConnectMsg();
|
||
break;
|
||
}
|
||
|
||
nDataSize = nCmdSize;
|
||
nRemainSize = nCmdSize;
|
||
pData = new uint8_t[nDataSize];
|
||
pDataEx = pData;
|
||
}
|
||
}
|
||
}
|
||
else if (6 == nHeadDataLen)
|
||
{
|
||
if ((0x80 | 0x09) == headData[0]) // PING帧
|
||
{
|
||
nHeadDataLen = 0;
|
||
|
||
p->Pong();
|
||
}
|
||
else if ((0x80 | 0x0A) == headData[0]) // PONG帧
|
||
{
|
||
nHeadDataLen = 0;
|
||
}
|
||
}
|
||
else if (10 == nHeadDataLen)
|
||
{
|
||
if ((headData[1] & 0x7F) == 127) // 这里一定会等于127
|
||
{
|
||
uint32_t nCmdSizeHigh = ntohl(*(uint32_t*)&headData[2]);
|
||
uint32_t nCmdSize = ntohl(*(uint32_t*)&headData[6]);
|
||
nHeadDataLen = 0;
|
||
|
||
if ((0 != nCmdSizeHigh) || (0 == nCmdSize))
|
||
{
|
||
p->PostDisConnectMsg();
|
||
break;
|
||
}
|
||
|
||
nDataSize = nCmdSize;
|
||
nRemainSize = nCmdSize;
|
||
pData = new uint8_t[nDataSize];
|
||
pDataEx = pData;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (4 != nMaskCount)
|
||
{
|
||
uint8_t b = *pBuffer;
|
||
++pBuffer;
|
||
--nBufferSize;
|
||
vMask[nMaskCount] = b;
|
||
++nMaskCount;
|
||
}
|
||
else
|
||
{
|
||
int nWriteSize = HGMIN(nBufferSize, nRemainSize);
|
||
memcpy(pDataEx, pBuffer, nWriteSize);
|
||
pBuffer += nWriteSize;
|
||
nBufferSize -= nWriteSize;
|
||
pDataEx += nWriteSize;
|
||
nRemainSize -= nWriteSize;
|
||
|
||
if (0 == nRemainSize)
|
||
{
|
||
assert(pDataEx == pData + nDataSize);
|
||
|
||
for (int i = 0; i < nDataSize; ++i)
|
||
{
|
||
int j = i % 4;
|
||
pData[i] = pData[i] ^ vMask[j];
|
||
vAllData.push_back(pData[i]);
|
||
}
|
||
|
||
delete[] pData;
|
||
pData = NULL;
|
||
nDataSize = 0;
|
||
nMaskCount = 0;
|
||
|
||
if (bHandle)
|
||
{
|
||
p->PostCmdMsg(&vAllData[0], (HGUInt)vAllData.size());
|
||
|
||
bHandle = false;
|
||
vAllData.clear();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (NULL != pData)
|
||
{
|
||
delete[] pData;
|
||
pData = NULL;
|
||
nDataSize = 0;
|
||
nMaskCount = 0;
|
||
}
|
||
}
|
||
|
||
int WebUser::sane_ex_callback(SANE_Handle hdev, int code, void* data, unsigned int* len, void* param)
|
||
{
|
||
(void)hdev;
|
||
(void)len;
|
||
|
||
WebUser* p = (WebUser*)param;
|
||
switch (code)
|
||
{
|
||
case SANE_EVENT_DEVICE_ARRIVED:
|
||
{
|
||
SANE_Device* sane_dev = (SANE_Device*)data;
|
||
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_DEVICE_ARRIVED, name=%s", Utf8ToStdString(sane_dev->name).c_str());
|
||
|
||
HGBase_EnterLock(p->m_lockName);
|
||
p->m_devNameList.push_back(sane_dev->name);
|
||
HGBase_LeaveLock(p->m_lockName);
|
||
}
|
||
break;
|
||
case SANE_EVENT_DEVICE_LEFT:
|
||
{
|
||
SANE_Device* sane_dev = (SANE_Device*)data;
|
||
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_DEVICE_LEFT, name=%s", Utf8ToStdString(sane_dev->name).c_str());
|
||
|
||
CloseDevParam* closeDevParam = new CloseDevParam;
|
||
closeDevParam->svr = p->m_server;
|
||
closeDevParam->usrId = p->m_id;
|
||
closeDevParam->devName = sane_dev->name;
|
||
|
||
HGMsg msg;
|
||
msg.id = MSGID_CLOSE_DEVICE;
|
||
msg.data = closeDevParam;
|
||
if (HGBASE_ERR_OK != HGBase_PostPumpMessage(p->m_msgPump, &msg))
|
||
{
|
||
delete closeDevParam;
|
||
}
|
||
|
||
HGBase_EnterLock(p->m_lockName);
|
||
for (int i = 0; i < (int)p->m_devNameList.size(); ++i)
|
||
{
|
||
if (0 == strcmp(sane_dev->name, p->m_devNameList[i].c_str()))
|
||
{
|
||
p->m_devNameList.erase(p->m_devNameList.begin() + i);
|
||
break;
|
||
}
|
||
}
|
||
HGBase_LeaveLock(p->m_lockName);
|
||
}
|
||
break;
|
||
case SANE_EVENT_WORKING:
|
||
{
|
||
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_WORKING, msg=%s", Utf8ToStdString((char*)data).c_str());
|
||
}
|
||
break;
|
||
case SANE_EVENT_SCAN_FINISHED:
|
||
{
|
||
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_SCAN_FINISHED, msg=%s", Utf8ToStdString((char*)data).c_str());
|
||
|
||
HGBase_SetEvent(p->m_scanEvent);
|
||
|
||
ScanFinishParam* scanFinishParam = new ScanFinishParam;
|
||
scanFinishParam->svr = p->m_server;
|
||
scanFinishParam->usrId = p->m_id;
|
||
|
||
HGMsg msg;
|
||
msg.id = MSGID_SCAN_FINISH;
|
||
msg.data = scanFinishParam;
|
||
if (HGBASE_ERR_OK != HGBase_PostPumpMessage(p->m_msgPump, &msg))
|
||
{
|
||
delete scanFinishParam;
|
||
}
|
||
|
||
int code = 0;
|
||
std::string result = "";
|
||
|
||
cJSON* retJson = cJSON_CreateObject();
|
||
if (NULL != retJson)
|
||
{
|
||
cJSON_AddItemToObject(retJson, "Func", cJSON_CreateString("ScanComplete"));
|
||
char str[10] = { 0 };
|
||
sprintf(str, "%d", code);
|
||
cJSON_AddItemToObject(retJson, "code", cJSON_CreateString(str));
|
||
cJSON_AddItemToObject(retJson, "result", cJSON_CreateString(StdStringToUtf8(result).c_str()));
|
||
|
||
char* resp = cJSON_Print(retJson);
|
||
if (NULL != resp)
|
||
{
|
||
p->PostEventMsg((const HGByte*)resp, (HGUInt)strlen(resp));
|
||
free(resp);
|
||
}
|
||
|
||
cJSON_Delete(retJson);
|
||
}
|
||
}
|
||
break;
|
||
case SANE_EVENT_STATUS:
|
||
{
|
||
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_STATUS, msg=%s", Utf8ToStdString((char*)data).c_str());
|
||
}
|
||
break;
|
||
case SANE_EVENT_ERROR:
|
||
{
|
||
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_ERROR, msg=%s", Utf8ToStdString((char*)data).c_str());
|
||
}
|
||
break;
|
||
case SANE_EVENT_IMAGE_OK:
|
||
{
|
||
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_IMAGE_OK");
|
||
|
||
SANE_Image* sane_img = (SANE_Image*)data;
|
||
|
||
HGUInt imgType = 0;
|
||
if (sane_img->header.format == SANE_FRAME_GRAY)
|
||
{
|
||
if (1 == sane_img->header.depth)
|
||
imgType = HGBASE_IMGTYPE_BINARY;
|
||
else if (8 == sane_img->header.depth)
|
||
imgType = HGBASE_IMGTYPE_GRAY;
|
||
}
|
||
else if (sane_img->header.format == SANE_FRAME_RGB)
|
||
imgType = HGBASE_IMGTYPE_RGB;
|
||
|
||
HGByte* data = sane_img->data;
|
||
HGImageInfo imgInfo = { (HGUInt)sane_img->header.pixels_per_line, (HGUInt)sane_img->header.lines,
|
||
imgType, (HGUInt)sane_img->header.bytes_per_line, HGBASE_IMGORIGIN_TOP };
|
||
|
||
HGImage img = NULL;
|
||
HGBase_CreateImageFromData(data, &imgInfo, NULL, 0, HGBASE_IMGORIGIN_TOP, &img);
|
||
if (NULL != img)
|
||
{
|
||
HGBase_SetImageDpi(img, p->m_dpi, p->m_dpi);
|
||
|
||
int code = 0;
|
||
std::string result = p->GetBase64(img);
|
||
|
||
cJSON* retJson = cJSON_CreateObject();
|
||
if (NULL != retJson)
|
||
{
|
||
cJSON_AddItemToObject(retJson, "Func", cJSON_CreateString("ImageSaveDone"));
|
||
char str[10] = { 0 };
|
||
sprintf(str, "%d", code);
|
||
cJSON_AddItemToObject(retJson, "code", cJSON_CreateString(str));
|
||
cJSON_AddItemToObject(retJson, "result", cJSON_CreateString(StdStringToUtf8(result).c_str()));
|
||
|
||
char* resp = cJSON_Print(retJson);
|
||
if (NULL != resp)
|
||
{
|
||
p->PostEventMsg((const HGByte*)resp, (HGUInt)strlen(resp));
|
||
free(resp);
|
||
}
|
||
|
||
cJSON_Delete(retJson);
|
||
}
|
||
|
||
HGBase_DestroyImage(img);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
std::string WebUser::GetBase64(HGImage image)
|
||
{
|
||
std::string ret;
|
||
|
||
if (NULL != image)
|
||
{
|
||
HGUInt xDpi, yDpi;
|
||
HGBase_GetImageDpi(image, &xDpi, &yDpi);
|
||
|
||
HGBuffer buffer = NULL;
|
||
HGJpegSaveInfo saveInfo;
|
||
saveInfo.densityUnit = HGIMGFMT_JPEGDENUNIT_INCH;
|
||
saveInfo.xDensity = xDpi;
|
||
saveInfo.yDensity = yDpi;
|
||
saveInfo.quality = m_jpgQuality;
|
||
HGImgFmt_SaveJpegImageToBuffer(image, &saveInfo, &buffer);
|
||
if (NULL != buffer)
|
||
{
|
||
HGByte* data = NULL;
|
||
HGBase_GetBufferData(buffer, &data);
|
||
HGUSize size = 0;
|
||
HGBase_GetBufferSize(buffer, &size);
|
||
|
||
HGSize base64Size = 0;
|
||
HGBase_Base64Encode(data, size, NULL, &base64Size);
|
||
HGByte* base64 = new HGByte[base64Size + 1];
|
||
HGBase_Base64Encode(data, size, base64, &base64Size);
|
||
base64[base64Size] = 0;
|
||
ret = (const char *)base64;
|
||
delete[] base64;
|
||
|
||
HGBase_DestroyBuffer(buffer);
|
||
}
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
HGBool WebUser::SetParam(const char* optionName, const HGVoid* data)
|
||
{
|
||
assert(NULL != m_devHandle);
|
||
if (NULL == data || NULL == optionName)
|
||
return HGFALSE;
|
||
|
||
HGBool ret = HGFALSE;
|
||
SANE_Int num_dev_options = 0;
|
||
sane_control_option(m_devHandle, 0, SANE_ACTION_GET_VALUE, &num_dev_options, NULL);
|
||
for (int i = 1; i < num_dev_options; ++i)
|
||
{
|
||
const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, i);
|
||
if (NULL == desp)
|
||
continue;
|
||
|
||
const char* name = desp->title;
|
||
while (' ' == *name)
|
||
++name;
|
||
|
||
if (0 == strcmp(optionName, name))
|
||
{
|
||
if (SANE_TYPE_STRING == desp->type)
|
||
{
|
||
SANE_Char* value = (SANE_Char*)((HGChar*)data);
|
||
if (NULL != value)
|
||
{
|
||
if (SANE_STATUS_GOOD == sane_control_option(m_devHandle, i, SANE_ACTION_SET_VALUE, value, NULL))
|
||
ret = HGTRUE;
|
||
}
|
||
}
|
||
else if (SANE_TYPE_INT == desp->type)
|
||
{
|
||
SANE_Int value = (SANE_Int)(*(HGInt*)data);
|
||
if (SANE_STATUS_GOOD == sane_control_option(m_devHandle, i, SANE_ACTION_SET_VALUE, &value, NULL))
|
||
ret = HGTRUE;
|
||
}
|
||
else if (SANE_TYPE_FIXED == desp->type)
|
||
{
|
||
SANE_Fixed value = SANE_FIX(*(HGDouble*)data);
|
||
if (SANE_STATUS_GOOD == sane_control_option(m_devHandle, i, SANE_ACTION_SET_VALUE, &value, NULL))
|
||
ret = HGTRUE;
|
||
}
|
||
else if (SANE_TYPE_BOOL == desp->type)
|
||
{
|
||
SANE_Bool value = (SANE_Bool)(*(HGBool*)data);
|
||
if (SANE_STATUS_GOOD == sane_control_option(m_devHandle, i, SANE_ACTION_SET_VALUE, &value, NULL))
|
||
ret = HGTRUE;
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
HGInt WebUser::GetDpi()
|
||
{
|
||
assert(NULL != m_devHandle);
|
||
HGInt dpi = 0;
|
||
|
||
SANE_Int num_dev_options = 0;
|
||
sane_control_option(m_devHandle, 0, SANE_ACTION_GET_VALUE, &num_dev_options, NULL);
|
||
for (int i = 1; i < num_dev_options; ++i)
|
||
{
|
||
const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, i);
|
||
if (NULL == desp)
|
||
continue;
|
||
|
||
const char* name = desp->title;
|
||
while (' ' == *name)
|
||
++name;
|
||
|
||
if (0 == strcmp(OPTION_TITLE_FBL, name))
|
||
{
|
||
if (SANE_TYPE_INT == desp->type)
|
||
{
|
||
SANE_Int value = 0;
|
||
sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL);
|
||
dpi = value;
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
return dpi;
|
||
}
|
||
|
||
bool WebUser::ShakeHand(const std::string& head)
|
||
{
|
||
std::string requestMethod;
|
||
std::string requestURIPath;
|
||
HttpPairs requestURIQueryInfos;
|
||
std::string requestURIFragment;
|
||
std::string httpVersion;
|
||
HttpPairs headInfos;
|
||
HttpHead::AnalysisHead(head, requestMethod, requestURIPath, requestURIQueryInfos,
|
||
requestURIFragment, httpVersion, headInfos);
|
||
|
||
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, head.c_str());
|
||
|
||
//if (std::string::npos == HttpHead::GetValue(headInfos, "Connection").find("Upgrade"))
|
||
// return false;
|
||
//if ("websocket" != HttpHead::GetValue(headInfos, "Upgrade"))
|
||
// return false;
|
||
|
||
std::string key = HttpHead::GetValue(headInfos, "Sec-WebSocket-Key");
|
||
if (key.empty())
|
||
return false;
|
||
|
||
key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||
|
||
unsigned int message_digest[5];
|
||
SHA1 sha;
|
||
sha.Reset();
|
||
sha << key.c_str();
|
||
sha.Result(message_digest);
|
||
|
||
for (int i = 0; i < 5; ++i)
|
||
message_digest[i] = htonl(message_digest[i]);
|
||
std::string serverKey = base64_encode((const unsigned char*)message_digest, 20);
|
||
|
||
std::string handShakeResp = "HTTP/1.1 101 Switching Protocols\r\n";
|
||
handShakeResp += "Upgrade: websocket\r\n";
|
||
handShakeResp += "Connection: Upgrade\r\n";
|
||
handShakeResp += "Sec-WebSocket-Accept:";
|
||
handShakeResp += serverKey;
|
||
handShakeResp += "\r\n\r\n";
|
||
send(m_sockConn, handShakeResp.c_str(), (int)handShakeResp.length(), 0);
|
||
return true;
|
||
}
|
||
|
||
void WebUser::Pong()
|
||
{
|
||
uint8_t vHead[2];
|
||
vHead[0] = 0x80 | 0x0A;
|
||
vHead[1] = 0;
|
||
|
||
HGBase_EnterLock(m_lock);
|
||
send(m_sockConn, (const char*)vHead, 2, 0);
|
||
HGBase_LeaveLock(m_lock);
|
||
}
|
||
|
||
bool WebUser::SendResponse(const HGByte* data, HGUInt size, HGBool text)
|
||
{
|
||
if (NULL == data || 0 == size)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
uint32_t nHeadLen = 0;
|
||
|
||
uint8_t vHead[20] = { 0 };
|
||
vHead[0] = text ? (0x80 | 0x01) : (0x80 | 0x02);
|
||
if (size <= 125)
|
||
{
|
||
vHead[1] = (uint8_t)size;
|
||
nHeadLen = 2;
|
||
}
|
||
else if (size <= 0xFFFF)
|
||
{
|
||
vHead[1] = 126;
|
||
uint16_t payloadLength16b = htons((uint16_t)size);
|
||
memcpy(&vHead[2], &payloadLength16b, 2);
|
||
nHeadLen = 4;
|
||
}
|
||
else
|
||
{
|
||
vHead[1] = 127;
|
||
vHead[2] = 0;
|
||
vHead[3] = 0;
|
||
vHead[4] = 0;
|
||
vHead[5] = 0;
|
||
uint32_t payloadLength32b = htonl(size);
|
||
memcpy(&vHead[6], &payloadLength32b, 4);
|
||
nHeadLen = 10;
|
||
}
|
||
|
||
HGBase_EnterLock(m_lock);
|
||
send(m_sockConn, (const char*)vHead, nHeadLen, 0);
|
||
send(m_sockConn, (const char*)data, size, 0);
|
||
HGBase_LeaveLock(m_lock);
|
||
return true;
|
||
}
|