// ReadQuery status_t ServerVolume::ReadQuery(QueryIterator* _iterator, struct dirent* buffer, size_t bufferSize, int32 count, int32* countRead) { // get connection ServerConnection* serverConnection = fConnectionProvider->GetExistingServerConnection(); if (!serverConnection) return ERROR_NOT_CONNECTED; RequestConnection* connection = serverConnection->GetRequestConnection(); ServerQueryIterator* iterator = dynamic_cast<ServerQueryIterator*>(_iterator); *countRead = 0; for (;;) { // if the iterator hasn't cached any more share volume IDs, we need to // ask the server for the next entry if (!iterator->HasNextShareVolumeID()) { // prepare the request ReadQueryRequest request; request.cookie = iterator->GetRemoteCookie(); request.count = 1; // send the request ReadQueryReply* reply; status_t error = SendRequest(connection, &request, &reply); if (error != B_OK) RETURN_ERROR(error); ObjectDeleter<Request> replyDeleter(reply); if (reply->error != B_OK) RETURN_ERROR(reply->error); // check, if anything has been read at all if (reply->count == 0) { *countRead = 0; return B_OK; } // update the iterator error = iterator->SetEntry(reply->clientVolumeIDs.GetElements(), reply->clientVolumeIDs.CountElements(), reply->dirInfo, reply->entryInfo); if (error != B_OK) return error; } // get the next concerned share volume and delegate the rest of the work int32 volumeID = iterator->NextShareVolumeID(); ShareVolume* shareVolume = _GetShareVolume(volumeID); if (!shareVolume) continue; VolumePutter volumePutter(shareVolume); return shareVolume->GetQueryEntry(iterator->GetEntryInfo(), iterator->GetDirectoryInfo(), buffer, bufferSize, countRead); } }
QTSS_Error RedisSetDevice(Easy_DeviceInfo_Params* inParams) { OSMutexLocker mutexLock(&sMutex); if (!RedisConnect()) { return QTSS_NotConnected; } if (!inParams->serial_ || string(inParams->serial_).empty()) { return QTSS_BadArgument; } QTSS_Error theRet = QTSS_NoErr; do { string id(QTSServerInterface::GetServer()->GetCloudServiceNodeID()); auto hmset = Format("hmset %s:%s %s %s %s %s %s %s %s %s", string(EASY_REDIS_DEVICE), string(inParams->serial_), string(EASY_REDIS_DEVICE_TYPE), string(inParams->deviceType_), string(EASY_REDIS_TYPE), string(inParams->type_), string(EASY_REDIS_CHANNEL), string(inParams->channels_), string(EASY_REDIS_EASYCMS), id, string(EASY_REDIS_TOKEN), string(inParams->token_)); auto reply = static_cast<redisReply*>(redisCommand(redisContext_, hmset.c_str())); RedisReplyObjectDeleter replyDeleter(reply); if (!reply) { theRet = QTSS_NotConnected; break; } if (string(reply->str) == string("OK")) { auto expire = Format("expire %s:%s 150", string(EASY_REDIS_DEVICE), string(inParams->serial_)); auto replyExpire = static_cast<redisReply*>(redisCommand(redisContext_, expire.c_str())); RedisReplyObjectDeleter replyExpireDeleter(replyExpire); if (!replyExpire) { theRet = QTSS_NotConnected; break; } } else { theRet = QTSS_RequestFailed; } } while (0); if (theRet != QTSS_NoErr) { RedisErrorHandler(); } return theRet; }
bool RedisConnect() { if (sIfConSucess) { return true; } bool theRet = false; do { struct timeval timeout = { 2, 0 }; // 2 seconds redisContext_ = redisConnectWithTimeout(sRedis_IP, sRedisPort, timeout); if (!redisContext_ || redisContext_->err) { if (redisContext_) { printf("Redis context connect error \n"); } else { printf("Connection error: can't allocate redis context\n"); } theRet = false; break; } string auth = Format("auth %s", string(sRedisPassword)); redisReply* reply = static_cast<redisReply*>(redisCommand(redisContext_, auth.c_str())); RedisReplyObjectDeleter replyDeleter(reply); if (!reply || string(reply->str) != string("OK")) { printf("Redis auth error\n"); theRet = false; break; } theRet = true; sIfConSucess = true; printf("Connect Redis success\n"); } while (0); if (!theRet && redisContext_) { RedisErrorHandler(); } return theRet; }
// OpenQuery status_t ServerVolume::OpenQuery(const char* queryString, uint32 flags, port_id port, int32 token, QueryIterator** _iterator) { // TODO: Do nothing when there are no (mounted) shares. // get connection ServerConnection* serverConnection = fConnectionProvider->GetExistingServerConnection(); if (!serverConnection) return ERROR_NOT_CONNECTED; RequestConnection* connection = serverConnection->GetRequestConnection(); // create a query iterator and add it to the query manager ServerQueryIterator* iterator = new(std::nothrow) ServerQueryIterator(this); if (!iterator) return B_NO_MEMORY; QueryManager* queryManager = fVolumeManager->GetQueryManager(); status_t error = queryManager->AddIterator(iterator); if (error != B_OK) { delete iterator; return error; } QueryIteratorPutter iteratorPutter(queryManager, iterator); // prepare the request OpenQueryRequest request; request.queryString.SetTo(queryString); request.flags = flags; request.port = port; request.token = token; // send the request OpenQueryReply* reply; error = SendRequest(connection, &request, &reply); if (error != B_OK) RETURN_ERROR(error); ObjectDeleter<Request> replyDeleter(reply); if (reply->error != B_OK) RETURN_ERROR(reply->error); // set the result iterator->SetRemoteCookie(reply->cookie); *_iterator = iterator; iteratorPutter.Detach(); return B_OK; }
QTSS_Error RedisDelDevice(Easy_DeviceInfo_Params* inParams) { OSMutexLocker mutexLock(&sMutex); if (!RedisConnect()) { return QTSS_NotConnected; } if (!inParams->serial_ || string(inParams->serial_).empty()) { return QTSS_BadArgument; } QTSS_Error theRet = QTSS_NoErr; do { auto del = Format("del %s:%s", EASY_REDIS_DEVICE, string(inParams->serial_)); auto reply = static_cast<redisReply*>(redisCommand(redisContext_, del.c_str())); RedisReplyObjectDeleter replyDeleter(reply); if (!reply) { theRet = QTSS_NotConnected; break; } if (reply->integer == 0) { theRet = QTSS_RequestFailed; } } while (0); if (theRet != QTSS_NoErr) { RedisErrorHandler(); } return theRet; }
QTSS_Error RedisGetAssociatedDarwin(QTSS_GetAssociatedDarwin_Params* inParams) { OSMutexLocker mutexLock(&sMutex); if (!RedisConnect()) { return QTSS_NotConnected; } QTSS_Error theRet = QTSS_NoErr; do { string exists = Format("exists %s:%s/%s", string(EASY_REDIS_LIVE), string(inParams->inSerial), string(inParams->inChannel)); auto reply = static_cast<redisReply*>(redisCommand(redisContext_, exists.c_str())); RedisReplyObjectDeleter replyDeleter(reply); if (!reply) { theRet = QTSS_NotConnected; break; } if (reply->integer == 1) { string strTemp = Format("hmget %s:%s/%s %s", string(EASY_REDIS_LIVE), string(inParams->inSerial), string(inParams->inChannel), string(EASY_REDIS_EASYDARWIN)); auto replyHmget = static_cast<redisReply*>(redisCommand(redisContext_, strTemp.c_str())); RedisReplyObjectDeleter replyHmgetDeleter(replyHmget); if (!replyHmget) { theRet = QTSS_NotConnected; break; } string easydarwin = Format("%s:", string(EASY_REDIS_EASYDARWIN)); easydarwin += replyHmget->element[0]->str; strTemp = Format("hmget %s %s %s %s", easydarwin, string(EASY_REDIS_IP), string(EASY_REDIS_HTTP), string(EASY_REDIS_RTSP)); auto replyHmgetEasyDarwin = static_cast<redisReply*>(redisCommand(redisContext_, strTemp.c_str())); RedisReplyObjectDeleter replyHmgetEasyDarwinDeleter(replyHmgetEasyDarwin); if (!replyHmgetEasyDarwin) { theRet = QTSS_NotConnected; break; } if (replyHmgetEasyDarwin->type == EASY_REDIS_REPLY_NIL) { theRet = QTSS_RequestFailed; break;; } if (replyHmgetEasyDarwin->type == EASY_REDIS_REPLY_ARRAY && replyHmgetEasyDarwin->elements == 3) { bool ok = true; for (int i = 0; i < replyHmgetEasyDarwin->elements; ++i) { if (replyHmgetEasyDarwin->element[i]->type == EASY_REDIS_REPLY_NIL) { ok = ok && false; } } if (ok) { string ip(replyHmgetEasyDarwin->element[0]->str); string httpPort(replyHmgetEasyDarwin->element[1]->str); string rtspPort(replyHmgetEasyDarwin->element[2]->str); memcpy(inParams->outDssIP, ip.c_str(), ip.size()); memcpy(inParams->outHTTPPort, httpPort.c_str(), httpPort.size()); memcpy(inParams->outDssPort, rtspPort.c_str(), rtspPort.size()); inParams->isOn = true; } else { theRet = QTSS_RequestFailed; break; } } } else { string keys = Format("keys %s:*", string(EASY_REDIS_EASYDARWIN)); auto replyKeys = static_cast<redisReply*>(redisCommand(redisContext_, keys.c_str())); RedisReplyObjectDeleter replyKeysDeleter(replyKeys); if (!replyKeys) { theRet = QTSS_NotConnected; break; } if (replyKeys->elements > 0) { int eleIndex = -1, eleLoad = 0; for (size_t i = 0; i < replyKeys->elements; ++i) { auto replyTemp = replyKeys->element[i]; if (replyTemp->type == EASY_REDIS_REPLY_NIL) { continue; } string strTemp = Format("hmget %s %s %s %s %s ", string(replyTemp->str), string(EASY_REDIS_LOAD), string(EASY_REDIS_IP), string(EASY_REDIS_HTTP), string(EASY_REDIS_RTSP)); auto replyHmget = static_cast<redisReply*>(redisCommand(redisContext_, strTemp.c_str())); RedisReplyObjectDeleter replyHmgetDeleter(replyHmget); if (!replyHmget) { theRet = QTSS_NotConnected; break; } if (replyHmget->type == EASY_REDIS_REPLY_NIL) { continue; } auto loadReply = replyHmget->element[0]; auto ipReply = replyHmget->element[1]; auto httpReply = replyHmget->element[2]; auto rtspReply = replyHmget->element[3]; auto load = stoi(loadReply->str); string ip(ipReply->str); string http(httpReply->str); string rtsp(rtspReply->str); if (eleIndex == -1) { eleIndex = i; eleLoad = load; strncpy(inParams->outDssIP, ip.c_str(), ip.size()); strncpy(inParams->outHTTPPort, http.c_str(), http.size()); strncpy(inParams->outDssPort, rtsp.c_str(), rtsp.size()); } else { if (load < eleLoad)//find better { eleIndex = i; eleLoad = load; strncpy(inParams->outDssIP, ip.c_str(), ip.size()); strncpy(inParams->outHTTPPort, http.c_str(), http.size()); strncpy(inParams->outDssPort, rtsp.c_str(), rtsp.size()); } } } if (eleIndex == -1)//no one live { theRet = QTSS_Unimplemented; break; } else { inParams->isOn = false; } } else { theRet = QTSS_Unimplemented; break; } } } while (0); if (theRet != QTSS_NoErr) { RedisErrorHandler(); } return theRet; }
QTSS_Error RedisTTL() { OSMutexLocker mutexLock(&sMutex); QTSS_Error theRet = QTSS_NoErr; if (!RedisConnect()) { return QTSS_NotConnected; } string server(QTSServerInterface::GetServer()->GetServerName().Ptr); string id(QTSServerInterface::GetServer()->GetCloudServiceNodeID()); UInt32 load = QTSServerInterface::GetServer()->GetNumServiceSessions(); do { string expire = Format("expire %s:%s 15", server, id); redisReply* reply = static_cast<redisReply*>(redisCommand(redisContext_, expire.c_str())); RedisReplyObjectDeleter replyDeleter(reply); if (!reply) { theRet = QTSS_NotConnected; break; } if (reply->integer == 0) { string cmsIp(QTSServerInterface::GetServer()->GetPrefs()->GetServiceWANIP()); auto cmsPort = QTSServerInterface::GetServer()->GetPrefs()->GetServiceWANPort(); auto hmset = Format("hmset %s:%s %s %s %s %hu %s %lu", string(EASY_REDIS_EASYCMS), id, string(EASY_REDIS_IP), cmsIp, string(EASY_REDIS_PORT), cmsPort, string(EASY_REDIS_LOAD), load); auto replyHmset = static_cast<redisReply*>(redisCommand(redisContext_, hmset.c_str())); RedisReplyObjectDeleter replyHmsetDeleter(replyHmset); if (!replyHmset) { theRet = QTSS_NotConnected; break; } auto replyExpire = static_cast<redisReply*>(redisCommand(redisContext_, expire.c_str())); RedisReplyObjectDeleter replyExpireDeleter(replyExpire); if (!replyExpire) { theRet = QTSS_NotConnected; break; } } else if (reply->integer == 1) { auto hset = Format("hset %s:%s %s %lu", server, id, string(EASY_REDIS_LOAD), load); auto replyHset = static_cast<redisReply*>(redisCommand(redisContext_, hset.c_str())); RedisReplyObjectDeleter replyHsetDeleter(replyHset); if (!replyHset) { theRet = QTSS_NotConnected; break; } } } while (0); if (theRet != QTSS_NoErr) { RedisErrorHandler(); } return theRet; }
// Init status_t ServerConnection::Init(vnode_id connectionBrokenTarget) { if (!fServerInfo) RETURN_ERROR(B_BAD_VALUE); // create a connection broken event fConnectionBrokenEvent = new(std::nothrow) ConnectionBrokenEvent(connectionBrokenTarget); if (!fConnectionBrokenEvent) return B_NO_MEMORY; // get the server address const char* connectionMethod = fServerInfo->GetConnectionMethod(); HashString server; status_t error = fServerInfo->GetAddress().GetString(&server, false); if (error != B_OK) RETURN_ERROR(error); // create the volume map fVolumes = new(std::nothrow) VolumeMap; if (!fVolumes) RETURN_ERROR(B_NO_MEMORY); error = fVolumes->InitCheck(); if (error != B_OK) RETURN_ERROR(error); // establish the connection Connection* connection; ConnectionFactory factory; error = factory.CreateConnection(connectionMethod, server.GetString(), &connection); if (error != B_OK) RETURN_ERROR(error); // create a request connection fConnection = new(std::nothrow) RequestConnection(connection, this); if (!fConnection) { delete connection; RETURN_ERROR(B_NO_MEMORY); } error = fConnection->Init(); if (error != B_OK) return error; // send an `init connection request' // prepare the request InitConnectionRequest request; request.bigEndian = B_HOST_IS_BENDIAN; // send the request Request* _reply; error = fConnection->SendRequest(&request, &_reply); if (error != B_OK) return error; ObjectDeleter<Request> replyDeleter(_reply); // everything OK? InitConnectionReply* reply = dynamic_cast<InitConnectionReply*>(_reply); if (!reply) return B_BAD_DATA; if (reply->error != B_OK) return reply->error; fConnected = true; return B_OK; }