mas01cr@239: #include "audioDB.h" mas01cr@239: #include "adb.nsmap" mas01cr@239: mas01cr@239: /* Command-line client definitions */ mas01cr@239: mas01cr@239: // FIXME: this can't propagate the sequence length argument (used for mas01cr@239: // dudCount). See adb__status() definition for the other half of mas01cr@239: // this. -- CSR, 2007-10-01 mas01cr@239: void audioDB::ws_status(const char*dbName, char* hostport){ mas01cr@239: struct soap soap; mas01cr@239: adb__statusResponse adbStatusResponse; mas01cr@239: mas01cr@239: // Query an existing adb database mas01cr@239: soap_init(&soap); mas01cr@239: if(soap_call_adb__status(&soap,hostport,NULL,(char*)dbName,adbStatusResponse)==SOAP_OK) { mas01cr@239: std::cout << "numFiles = " << adbStatusResponse.result.numFiles << std::endl; mas01cr@239: std::cout << "dim = " << adbStatusResponse.result.dim << std::endl; mas01cr@239: std::cout << "length = " << adbStatusResponse.result.length << std::endl; mas01cr@239: std::cout << "dudCount = " << adbStatusResponse.result.dudCount << std::endl; mas01cr@239: std::cout << "nullCount = " << adbStatusResponse.result.nullCount << std::endl; mas01mc@324: std::cout << "flags = " << (adbStatusResponse.result.flags & 0x00FFFFFF) << std::endl; mas01cr@239: } else { mas01cr@550: char fault[MAXSTR]; mas01cr@550: soap_sprint_fault(&soap, fault, MAXSTR); mas01cr@550: error(fault); mas01cr@239: } mas01cr@239: mas01cr@239: soap_destroy(&soap); mas01cr@239: soap_end(&soap); mas01cr@239: soap_done(&soap); mas01cr@239: } mas01cr@239: mas01mc@334: void audioDB::ws_liszt(const char* dbName, char* Hostport){ mas01mc@334: struct soap soap; mas01mc@334: adb__lisztResponse adbLisztResponse; mas01mc@334: mas01mc@334: soap_init(&soap); mas01mc@334: if(soap_call_adb__liszt(&soap, hostport, NULL, (char*)dbName, lisztOffset, lisztLength, adbLisztResponse)==SOAP_OK){ mas01mc@334: for(int i = 0; i < adbLisztResponse.result.__sizeRkey; i++) { mas01mc@334: std::cout << "[" << i+lisztOffset << "] " << adbLisztResponse.result.Rkey[i] << " (" mas01mc@334: << adbLisztResponse.result.Rlen[i] << ")" << std::endl; mas01mc@334: } mas01mc@334: } else { mas01cr@550: char fault[MAXSTR]; mas01cr@550: soap_sprint_fault(&soap, fault, MAXSTR); mas01cr@550: error(fault); mas01mc@334: } mas01cr@550: soap_destroy(&soap); mas01cr@550: soap_end(&soap); mas01cr@550: soap_done(&soap); mas01mc@334: } mas01mc@334: mas01mc@308: // WS_QUERY (CLIENT SIDE) mas01mc@307: void audioDB::ws_query(const char*dbName, const char *featureFileName, const char* hostport){ mas01cr@239: struct soap soap; mas01cr@239: adb__queryResponse adbQueryResponse; mas01mc@329: VERB_LOG(1, "Calling fileName query on database %s with featureFile=%s\n", dbName, featureFileName); mas01cr@333: soap_init(&soap); mas01cr@333: if(soap_call_adb__query(&soap, hostport, NULL, (char *) dbName, mas01cr@333: (char *)featureFileName, (char *)trackFileName, mas01cr@333: (char *)timesFileName, (char *) powerFileName, mas01cr@333: queryType, queryPoint, mas01cr@333: pointNN, trackNN, sequenceLength, mas01cr@333: radius, absolute_threshold, relative_threshold, mas01mc@471: !usingQueryPoint, lsh_exact, no_unit_norming, mas01cr@333: adbQueryResponse) mas01cr@333: == SOAP_OK) { mas01cr@333: if(radius == 0) { mas01cr@333: for(int i=0; i on server" << endl; mas01mc@354: return SOAP_FAULT; mas01mc@354: } mas01mc@354: mas01mc@354: FILE* tmpFile = fdopen(tmpFid, "r+b"); mas01mc@354: if(!tmpFile){ mas01mc@354: cerr << "error opening <" << tmpFileName << "> for write" << endl; mas01mc@354: return SOAP_FAULT; mas01mc@354: } mas01mc@354: mas01mc@354: if(fwrite(&qVector.dim, sizeof(int), 1, tmpFile)!=1){ mas01mc@354: cerr << "error writing tmp file dim <"<< tmpFileName << ">" << endl; mas01mc@354: return SOAP_FAULT; mas01mc@354: } mas01mc@354: mas01mc@354: if(fwrite(qVector.v, sizeof(double), qVector.__sizev, tmpFile)!=(size_t)qVector.__sizev){ mas01mc@354: cerr << "error writing tmp file doubles <" << tmpFileName << ">" << endl; mas01mc@354: return SOAP_FAULT; mas01mc@354: } mas01mc@354: mas01mc@354: // Close the file so that a new FD can be opened mas01mc@354: fclose(tmpFile); mas01mc@354: mas01mc@354: char tmpFileName2[] = "/tmp/adbP_XXXXXX"; mas01mc@354: int tmpFid2 = 0; mas01mc@354: FILE* tmpFile2 = NULL; mas01mc@354: mas01mc@354: // Check if powers have been passed and write accordingly mas01mc@354: if(qVector.__sizep){ mas01mc@354: tmpFid2 = mkstemp(tmpFileName2); mas01mc@354: tmpFile2 = fdopen(tmpFid2, "r+b"); mas01mc@354: if(!tmpFile2){ mas01mc@354: cerr << "error opening power file <" << tmpFileName2 << "> for write" << endl; mas01mc@354: return SOAP_FAULT; mas01mc@354: } mas01mc@354: int pSize=1; mas01mc@354: if(fwrite(&pSize, sizeof(int), 1, tmpFile2)!=1){ mas01mc@354: cerr << "error writing tmp power file dim <"<< tmpFileName2 << ">" << endl; mas01mc@354: return SOAP_FAULT; mas01mc@354: } mas01mc@354: mas01mc@354: if(fwrite(qVector.p, sizeof(double), qVector.__sizep, tmpFile2)!=(size_t)qVector.__sizep){ mas01mc@354: cerr << "error writing tmp power file doubles <" << tmpFileName2 << ">" << endl; mas01mc@354: return SOAP_FAULT; mas01mc@354: } mas01mc@354: fclose(tmpFile2); mas01mc@354: } mas01mc@354: mas01mc@354: // fix up sequenceLength if it isn't provided, we know what the caller wants by the size of the shingle mas01mc@354: // and the feature dimensionality mas01mc@354: if(!sequenceLength) mas01mc@354: sequenceLength = qVector.__sizev/qVector.dim; mas01mc@354: mas01mc@354: int retVal = adb__query(soap, dbName, tmpFileName, keyList, timesFileName, qVector.__sizep?tmpFileName2:0, mas01mc@354: queryType, queryPos, pointNN, trackNN, sequenceLength, radius, mas01mc@471: absolute_threshold, relative_threshold, exhaustive, lsh_exact, no_unit_norming, adbQueryResponse); mas01mc@354: mas01mc@354: return retVal; mas01mc@354: } mas01mc@354: mas01cr@239: /* Server loop */ mas01cr@239: void audioDB::startServer(){ mas01cr@239: struct soap soap; mas01cr@239: int m, s; // master and slave sockets mas01cr@239: soap_init(&soap); mas01cr@239: // FIXME: largely this use of SO_REUSEADDR is to make writing (and mas01cr@239: // running) test cases more convenient, so that multiple test runs mas01cr@239: // in close succession don't fail because of a bin() error. mas01cr@239: // Investigate whether there are any potential drawbacks in this, mas01cr@239: // and also whether there's a better way to write the tests. -- mas01cr@239: // CSR, 2007-10-03 mas01cr@239: soap.bind_flags |= SO_REUSEADDR; mas01cr@239: m = soap_bind(&soap, NULL, port, 100); mas01cr@239: if (m < 0) mas01cr@239: soap_print_fault(&soap, stderr); mas01cr@239: else mas01cr@239: { mas01cr@239: fprintf(stderr, "Socket connection successful: master socket = %d\n", m); mas01cr@498: /* FIXME: we used to have a global cache of a single LSH index mas01cr@498: * here. CSR removed it because it interacted badly with mas01cr@498: * APIification of querying, replacing it with a per-open-adb mas01cr@498: * cache; we should try to take advantage of that instead. mas01cr@498: */ mas01cr@498: mas01mc@324: // Server-side path prefix to databases and features mas01mc@324: if(adb_root) mas01mc@324: SERVER_ADB_ROOT = (char*)adb_root; // Server-side database root mas01mc@324: if(adb_feature_root) mas01mc@324: SERVER_ADB_FEATURE_ROOT = (char*)adb_feature_root; // Server-side features root mas01mc@338: mas01mc@338: isServer = 1; // From this point, errors are reported via SOAP to the client mas01cr@239: for (int i = 1; ; i++) mas01cr@239: { mas01cr@239: s = soap_accept(&soap); mas01cr@239: if (s < 0) mas01cr@239: { mas01cr@239: soap_print_fault(&soap, stderr); mas01cr@239: break; mas01cr@239: } mas01cr@239: /* FIXME: find a way to play nice with logging when run from mas01cr@239: /etc/init.d scripts: at present this just goes nowhere */ mas01cr@239: fprintf(stderr, "%d: accepted connection from IP=%lu.%lu.%lu.%lu socket=%d\n", i, mas01cr@239: (soap.ip >> 24)&0xFF, (soap.ip >> 16)&0xFF, (soap.ip >> 8)&0xFF, soap.ip&0xFF, s); mas01cr@239: if (soap_serve(&soap) != SOAP_OK) // process RPC request mas01cr@239: soap_print_fault(&soap, stderr); // print error mas01cr@239: fprintf(stderr, "request served\n"); mas01cr@239: soap_destroy(&soap); // clean up class instances mas01cr@239: soap_end(&soap); // clean up everything and close socket mas01cr@239: } mas01cr@239: } mas01cr@239: soap_done(&soap); // close master socket and detach environment mas01cr@239: }