#include "WSUser.h" #include "WSServer.h" #include "ManagerV2.h" #include "base/HGInfo.h" #include "cJSON.h" #include "sha1.h" #include "base64.h" #include "HGString.h" namespace ver_2 { 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 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 || p->type == cJSON_NULL) { ret = (p->type == cJSON_String) ? p->valuestring : ""; if (NULL != find) *find = true; } break; } p = p->next; } return ret; } static std::vector GetJsonStringListValue(cJSON* json, const std::string& key, bool* find = NULL) { std::vector 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; } #if defined(HG_CMP_MSC) WSUser::WSUser(WebServer* server, HGUInt id, const std::string& ip, uint16_t port, SOCKET sockConn) #else WSUser::WSUser(WebServer* server, HGUInt id, const std::string& ip, uint16_t port, int sockConn) #endif : WebUser(server, id, ip, port, sockConn) { GetManager()->SetSaneEvent(SaneEvent2, this); GetManager()->SetSaneImageCallback(SaneImageCallback2, this); } WSUser::~WSUser() { GetManager()->DeinitDevice(); GetManager()->ResetSaneImageCallback(); GetManager()->ResetSaneEvent(); } ManagerV2* WSUser::GetManager() { return ((WSServer*)m_server)->GetManger(); } void WSUser::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"); std::string iden = GetJsonStringValue(json, "iden"); if ("set_global_config" == func) { GlobalConfig cfg; cfg.fileSavePath = Utf8ToStdString(GetJsonStringValue(json, "file_save_path")); cfg.fileNamePrefix = Utf8ToStdString(GetJsonStringValue(json, "file_name_prefix")); cfg.fileNameMode = GetJsonStringValue(json, "file_name_mode"); cfg.imageFormat = GetJsonStringValue(json, "image_format"); cfg.imageJpegQuality = GetJsonIntValue(json, "image_jpeg_quality"); cfg.imageTiffCompression = GetJsonStringValue(json, "image_tiff_compression"); cfg.imageTiffJpegQuality = GetJsonIntValue(json, "image_tiff_jpeg_quality"); cfg.uploadHttpHost = GetJsonStringValue(json, "upload_http_host"); cfg.uploadHttpPort = GetJsonIntValue(json, "upload_http_port"); cfg.uploadHttpPath = GetJsonStringValue(json, "upload_http_path"); cfg.uploadFtpUser = GetJsonStringValue(json, "upload_ftp_user"); cfg.uploadFtpPassword = GetJsonStringValue(json, "upload_ftp_password"); cfg.uploadFtpHost = GetJsonStringValue(json, "upload_ftp_host"); cfg.uploadFtpPort = GetJsonIntValue(json, "upload_ftp_port"); int ret = GetManager()->SetGlobalConfig(cfg); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\"}"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str()); SendResponse((const HGByte *)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("get_global_config" == func) { GlobalConfig cfg; int ret = GetManager()->GetGlobalConfig(cfg); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\", "; fmt += "\"file_save_path\":\"%s\", "; fmt += "\"file_name_prefix\":\"%s\", "; fmt += "\"file_name_mode\":\"%s\", "; fmt += "\"image_format\":\"%s\", "; fmt += "\"image_jpeg_quality\":%d, "; fmt += "\"image_tiff_compression\":\"%s\", "; fmt += "\"image_tiff_jpeg_quality\":%d, "; fmt += "\"upload_http_host\":\"%s\", "; fmt += "\"upload_http_port\":%d, "; fmt += "\"upload_http_path\":\"%s\", "; fmt += "\"upload_ftp_user\":\"%s\", "; fmt += "\"upload_ftp_password\":\"%s\", "; fmt += "\"upload_ftp_host\":\"%s\", "; fmt += "\"upload_ftp_port\":%d}"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str(), StdStringToUtf8(strToJson(cfg.fileSavePath)).c_str(), StdStringToUtf8(strToJson(cfg.fileNamePrefix)).c_str(), cfg.fileNameMode.c_str(), cfg.imageFormat.c_str(), cfg.imageJpegQuality, cfg.imageTiffCompression.c_str(), cfg.imageTiffJpegQuality, cfg.uploadHttpHost.c_str(), cfg.uploadHttpPort, strToJson(cfg.uploadHttpPath).c_str(), cfg.uploadFtpUser.c_str(), cfg.uploadFtpPassword.c_str(), cfg.uploadFtpHost.c_str(), cfg.uploadFtpPort); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("load_local_image" == func) { std::string imagePath = Utf8ToStdString(GetJsonStringValue(json, "image_path")); std::string imageBase64; int ret = GetManager()->LoadLocalImage(imagePath, imageBase64); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\", "; fmt += "\"image_base64\":\"%s\"}"; char *resp = new char [1024 + imageBase64.size()]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str(), imageBase64.c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); delete[] resp; } else if ("save_local_image" == func) { std::string imageBase64 = GetJsonStringValue(json, "image_base64"); std::string imagePath; int ret = GetManager()->SaveLocalImage(imageBase64, imagePath); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\", "; fmt += "\"image_path\":\"%s\"}"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str(), StdStringToUtf8(strToJson(imagePath)).c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("delete_local_file" == func) { std::string filePath = Utf8ToStdString(GetJsonStringValue(json, "file_path")); int ret = GetManager()->DeleteLocalFile(filePath); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\"}"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("clear_global_file_save_path" == func) { int ret = GetManager()->ClearGlobalFileSavePath(); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\"}"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("merge_local_image" == func) { std::vector imagePathList = GetJsonStringListValue(json, "image_path_list"); for (int i = 0; i < (int)imagePathList.size(); ++i) imagePathList[i] = Utf8ToStdString(imagePathList[i]); std::string mode = GetJsonStringValue(json, "mode"); std::string align = GetJsonStringValue(json, "align"); int interval = GetJsonIntValue(json, "interval"); std::string outImagePath; int ret = GetManager()->MergeLocalImage(imagePathList, mode, align, interval, outImagePath); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\", "; fmt += "\"image_path\":\"%s\"}"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str(), StdStringToUtf8(strToJson(outImagePath)).c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("local_make_multi_image" == func) { std::vector imagePathList = GetJsonStringListValue(json, "image_path_list"); for (int i = 0; i < (int)imagePathList.size(); ++i) imagePathList[i] = Utf8ToStdString(imagePathList[i]); std::string format = GetJsonStringValue(json, "format"); std::string tiffCompression = GetJsonStringValue(json, "tiff_compression"); int tiffJpegQuality = GetJsonIntValue(json, "tiff_jpeg_quality"); std::string outImagePath; int ret = GetManager()->LocalMakeMultiImage(imagePathList, format, tiffCompression, tiffJpegQuality, outImagePath); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\", "; fmt += "\"image_path\":\"%s\"}"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str(), StdStringToUtf8(strToJson(outImagePath)).c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("split_local_image" == func) { std::string imagePath = Utf8ToStdString(GetJsonStringValue(json, "image_path")); std::string mode = GetJsonStringValue(json, "mode"); int location = GetJsonIntValue(json, "location"); std::vector outImagePathList; int ret = GetManager()->SplitLocalImage(imagePath, mode, location, outImagePathList); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\", "; fmt += "\"image_path_list\":%s}"; std::string pathList = "["; for (int i = 0; i < (int)outImagePathList.size(); ++i) { pathList += "\""; pathList += StdStringToUtf8(strToJson(outImagePathList[i])); pathList += "\""; if (i != (int)outImagePathList.size() - 1) { pathList += ", "; } } pathList += "]"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str(), pathList.c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("local_make_zip_file" == func) { std::vector filePathList = GetJsonStringListValue(json, "file_path_list"); for (int i = 0; i < (int)filePathList.size(); ++i) filePathList[i] = Utf8ToStdString(filePathList[i]); std::string outZipPath; int ret = GetManager()->LocalMakeZipFile(filePathList, outZipPath); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\", "; fmt += "\"zip_path\":\"%s\"}"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str(), StdStringToUtf8(strToJson(outZipPath)).c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("local_image_deskew" == func) { std::string imagePath = Utf8ToStdString(GetJsonStringValue(json, "image_path")); std::string outImagePath; int ret = GetManager()->LocalImageDeskew(imagePath, outImagePath); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\", "; fmt += "\"image_path\":\"%s\"}"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str(), StdStringToUtf8(strToJson(outImagePath)).c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("upload_local_file" == func) { std::string filePath = Utf8ToStdString(GetJsonStringValue(json, "file_path")); std::string mode = GetJsonStringValue(json, "upload_mode"); std::string remoteFilePath = Utf8ToStdString(GetJsonStringValue(json, "remote_file_path")); int ret = GetManager()->UploadLocalFile(filePath, mode, remoteFilePath); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\"}"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("init_device" == func) { int ret = GetManager()->InitDevice(); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\"}"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("deinit_device" == func) { int ret = GetManager()->DeinitDevice(); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\"}"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("get_device_name_list" == func) { std::vector devNameList; int ret = GetManager()->GetDeviceNameList(devNameList); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\", "; fmt += "\"device_name_list\":%s}"; std::string nameList = "["; for (int i = 0; i < (int)devNameList.size(); ++i) { nameList += "\""; nameList += devNameList[i]; nameList += "\""; if (i != (int)devNameList.size() - 1) { nameList += ", "; } } nameList += "]"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str(), nameList.c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("open_device" == func) { std::string devName = GetJsonStringValue(json, "device_name"); int ret = GetManager()->OpenDevice(devName); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\"}"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("close_device" == func) { int ret = GetManager()->CloseDevice(); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\"}"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("set_device_param" == func) { } else if ("get_device_param" == func) { } else if ("get_curr_device_name" == func) { std::string devName; int ret = GetManager()->GetCurrDeviceName(devName); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\", "; fmt += "\"device_name\":\"%s\"}"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str(), devName.c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("start_scan" == func) { int ret = GetManager()->StartScan(); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\"}"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } else if ("stop_scan" == func) { int ret = GetManager()->StopScan(); std::string errInfo; if (0 != ret) errInfo = StdStringToUtf8("错误"); std::string fmt; fmt += "{\"func\":\"%s\", "; fmt += "\"iden\":\"%s\", "; fmt += "\"ret\":%d, "; fmt += "\"err_info\":\"%s\"}"; char resp[1024]; sprintf(resp, fmt.c_str(), func.c_str(), iden.c_str(), ret, errInfo.c_str()); SendResponse((const HGByte*)resp, (HGUInt)strlen(resp), HGTRUE); } cJSON_Delete(json); } } void WSUser::HandleEvent(const WSEvtParam* param) { assert(NULL != param && m_id == param->usrId); SendResponse(param->data, param->size, HGTRUE); } void WSUser::PostCmdMsg(const HGByte* data, HGUInt dataSize) { WSCmdParam* param = new WSCmdParam; param->svr = (WSServer*)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_server->GetMsgPump(), &msg)) { delete[] param->data; param->size = 0; delete param; } } void WSUser::PostEventMsg(const HGByte* data, HGUInt dataSize) { WSEvtParam* param = new WSEvtParam; param->svr = (WSServer*)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_server->GetMsgPump(), &msg)) { delete[] param->data; param->size = 0; delete param; } } void WSUser::ThreadFunc() { HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "WSUser::ThreadFunc"); 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 vAllData; while (1) { if (0 == nBufferSize) { int len = recv(m_sockConn, chBuffer, 2048, 0); if (len <= 0) { // 这里跳出,可能是服务器关闭了socketConn,或者客户端关闭了socket,或者网络断开 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 = ShakeHand(connectData); connectData.clear(); if (!shakeRet) { 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]) // 断开连接 { 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 // 帧错误,断开连接 { PostDisConnectMsg(); break; } } else if (2 == nHeadDataLen) { if (0 == (headData[1] & 0x80)) // 必须经过掩码处理 { PostDisConnectMsg(); break; } if ((0x80 | 0x09) == headData[0]) // PING帧 { if (0x80 != headData[1]) { PostDisConnectMsg(); break; } } else if ((0x80 | 0x0A) == headData[0]) // PONG帧 { if (0x80 != headData[1]) { PostDisConnectMsg(); break; } } else { if ((headData[1] & 0x7F) <= 125) { uint32_t nCmdSize = (headData[1] & 0x7F); nHeadDataLen = 0; if (0 == nCmdSize) { 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) { 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; 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)) { 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) { PostCmdMsg(&vAllData[0], (HGUInt)vAllData.size()); bHandle = false; vAllData.clear(); } } } } } } if (NULL != pData) { delete[] pData; pData = NULL; nDataSize = 0; nMaskCount = 0; } } void WSUser::SaneEvent2(int code, const char* str, bool err, void* param) { WSUser* p = (WSUser*)param; if (code == SANEEVENT_ARRIVE) { char resp[1024]; sprintf(resp, "{\"func\":\"%s\", \"iden\":\"%s\", \"device_name\":\"%s\"}", "device_arrive", "", str); p->PostEventMsg((const HGByte*)resp, (HGUInt)strlen(resp)); } else if (code == SANEEVENT_REMOVE) { char resp[1024]; sprintf(resp, "{\"func\":\"%s\", \"iden\":\"%s\", \"device_name\":\"%s\"}", "device_remove", "", str); p->PostEventMsg((const HGByte*)resp, (HGUInt)strlen(resp)); } else if (code == SANEEVENT_WORKING) { char resp[1024]; sprintf(resp, "{\"func\":\"%s\", \"iden\":\"%s\"}", "scan_begin", ""); p->PostEventMsg((const HGByte*)resp, (HGUInt)strlen(resp)); sprintf(resp, "{\"func\":\"%s\", \"iden\":\"%s\", \"is_error\":%s, \"info\":\"%s\"}", "scan_info", "", err ? "true" : "false", str); p->PostEventMsg((const HGByte*)resp, (HGUInt)strlen(resp)); } else if (code == SANEEVENT_FINISH) { char resp[1024]; sprintf(resp, "{\"func\":\"%s\", \"iden\":\"%s\", \"is_error\":%s, \"info\":\"%s\"}", "scan_info", "", err ? "true" : "false", str); p->PostEventMsg((const HGByte*)resp, (HGUInt)strlen(resp)); sprintf(resp, "{\"func\":\"%s\", \"iden\":\"%s\"}", "scan_end", ""); p->PostEventMsg((const HGByte*)resp, (HGUInt)strlen(resp)); } else if (code == SANEEVENT_STATUS || code == SANEEVENT_ERROR) { char resp[1024]; sprintf(resp, "{\"func\":\"%s\", \"iden\":\"%s\", \"is_error\":%s, \"info\":\"%s\"}", "scan_info", "", err ? "true" : "false", str); p->PostEventMsg((const HGByte*)resp, (HGUInt)strlen(resp)); } } void WSUser::SaneImageCallback2(const char* path, void* param) { WSUser* p = (WSUser*)param; char resp[1024]; sprintf(resp, "{\"func\":\"%s\", \"iden\":\"%s\", \"image_path\":\"%s\"}", "scan_image", "", StdStringToUtf8(strToJson(path)).c_str()); p->PostEventMsg((const HGByte*)resp, (HGUInt)strlen(resp)); } std::string WSUser::strToJson(const std::string str) { std::string ret; for (size_t i = 0; i < str.size(); i++) { char c = str[i]; switch (c) { case '\"': ret.append("\\\""); break; case '\\': ret.append("\\\\"); break; case '/': ret.append("\\/"); break; case '\b': ret.append("\\b"); break; case '\f': ret.append("\\f"); break; case '\n': ret.append("\\n"); break; case '\r': ret.append("\\r"); break; case '\t': ret.append("\\t"); break; default: ret.push_back(c); } } return ret; } bool WSUser::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); if ("Upgrade" != HttpHead::GetValue(headInfos, "Connection")) 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 WSUser::Pong() { uint8_t vHead[2]; vHead[0] = 0x80 | 0x0A; vHead[1] = 0; HGBase_EnterLock(m_cs); send(m_sockConn, (const char*)vHead, 2, 0); HGBase_LeaveLock(m_cs); } bool WSUser::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_cs); send(m_sockConn, (const char*)vHead, nHeadLen, 0); send(m_sockConn, (const char*)data, size, 0); HGBase_LeaveLock(m_cs); return true; } }