/* **************************************************************************** * * mongoUnsubscribeContext - */ HttpStatusCode mongoUnsubscribeContext(UnsubscribeContextRequest* requestP, UnsubscribeContextResponse* responseP, const std::string& tenant) { bool reqSemTaken; BSONObj sub; DBClientBase* connection = NULL; reqSemTake(__FUNCTION__, "ngsi10 unsubscribe request", SemWriteOp, &reqSemTaken); LM_T(LmtMongo, ("Unsubscribe Context")); /* No matter if success or failure, the subscriptionId in the response is always the one * in the request */ responseP->subscriptionId = requestP->subscriptionId; if (responseP->subscriptionId.get() == "") { responseP->statusCode.fill(SccContextElementNotFound); LM_W(("Bad Input (no subscriptionId)")); return SccOk; } LM_T(LmtMongo, ("findOne() in '%s' collection _id '%s'}", getSubscribeContextCollectionName(tenant).c_str(), requestP->subscriptionId.get().c_str())); /* Look for document */ connection = getMongoConnection(); try { OID id = OID(requestP->subscriptionId.get()); sub = connection->findOne(getSubscribeContextCollectionName(tenant).c_str(), BSON("_id" << id)); releaseMongoConnection(connection); LM_I(("Database Operation Successful (findOne _id: %s)", id.toString().c_str())); } catch (const AssertionException &e) { releaseMongoConnection(connection); reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request (mongo assertion exception)", reqSemTaken); // // This happens when OID format is wrong // FIXME: this checking should be done at parsing stage, without progressing to // mongoBackend. By the moment we can live this here, but we should remove in the future // (old issue #95) // responseP->statusCode.fill(SccContextElementNotFound); LM_W(("Bad Input (invalid OID format)")); return SccOk; } catch (const DBException &e) { releaseMongoConnection(connection); reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request (mongo db exception)", reqSemTaken); responseP->statusCode.fill(SccReceiverInternalError, std::string("collection: ") + getSubscribeContextCollectionName(tenant).c_str() + " - findOne() _id: " + requestP->subscriptionId.get() + " - exception: " + e.what()); LM_E(("Database Error (%s)", responseP->statusCode.details.c_str())); return SccOk; } catch (...) { releaseMongoConnection(connection); reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request (mongo generic exception)", reqSemTaken); responseP->statusCode.fill(SccReceiverInternalError, std::string("collection: ") + getSubscribeContextCollectionName(tenant).c_str() + " - findOne() _id: " + requestP->subscriptionId.get() + " - exception: " + "generic"); LM_E(("Database Error (%s)", responseP->statusCode.details.c_str())); return SccOk; } if (sub.isEmpty()) { reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request (no subscriptions found)", reqSemTaken); responseP->statusCode.fill(SccContextElementNotFound, std::string("subscriptionId: /") + requestP->subscriptionId.get() + "/"); return SccOk; } /* Remove document in MongoDB */ // FIXME: I will prefer to do the find and remove in a single operation. Is the some similar // to findAndModify for this? LM_T(LmtMongo, ("remove() in '%s' collection _id '%s'}", getSubscribeContextCollectionName(tenant).c_str(), requestP->subscriptionId.get().c_str())); connection = getMongoConnection(); try { connection->remove(getSubscribeContextCollectionName(tenant).c_str(), BSON("_id" << OID(requestP->subscriptionId.get()))); releaseMongoConnection(connection); LM_I(("Database Operation Successful (remove _id: %s)", requestP->subscriptionId.get().c_str())); } catch (const DBException &e) { releaseMongoConnection(connection); reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request (mongo db exception)", reqSemTaken); responseP->statusCode.fill(SccReceiverInternalError, std::string("collection: ") + getSubscribeContextCollectionName(tenant).c_str() + " - remove() _id: " + requestP->subscriptionId.get().c_str() + " - exception: " + e.what()); LM_E(("Database Error (%s)", responseP->statusCode.details.c_str())); return SccOk; } catch (...) { releaseMongoConnection(connection); reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request (mongo generic exception)", reqSemTaken); responseP->statusCode.fill(SccReceiverInternalError, std::string("collection: ") + getSubscribeContextCollectionName(tenant).c_str() + " - remove() _id: " + requestP->subscriptionId.get().c_str() + " - exception: " + "generic"); LM_E(("Database Error (%s)", responseP->statusCode.details.c_str())); return SccOk; } /* Destroy any previous ONTIMEINTERVAL thread */ getNotifier()->destroyOntimeIntervalThreads(requestP->subscriptionId.get()); responseP->statusCode.fill(SccOk); reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request", reqSemTaken); // // Removing subscription from cache // subCache->remove(tenant, "", requestP->subscriptionId.get()); return SccOk; }
/* **************************************************************************** * * mongoUpdateContextSubscription - */ HttpStatusCode mongoUpdateContextSubscription(UpdateContextSubscriptionRequest* requestP, UpdateContextSubscriptionResponse* responseP, Format inFormat, const std::string& tenant) { reqSemTake(__FUNCTION__, "ngsi10 update subscription request"); LM_T(LmtMongo, ("Update Context Subscription")); DBClientBase* connection = getMongoConnection(); /* Look for document */ BSONObj sub; try { OID id = OID(requestP->subscriptionId.get()); mongoSemTake(__FUNCTION__, "findOne in SubscribeContextCollection"); sub = connection->findOne(getSubscribeContextCollectionName(tenant).c_str(), BSON("_id" << id)); mongoSemGive(__FUNCTION__, "findOne in SubscribeContextCollection"); LM_I(("Database Operation Successful (findOne _id: %s)", id.toString().c_str())); } catch (const AssertionException &e) { /* This happens when OID format is wrong */ // FIXME P4: this checking should be done at the parsing stage, without progressing to // mongoBackend. For the moment we can leave this here, but we should remove it in the future // (old issue #95) mongoSemGive(__FUNCTION__, "findOne in SubscribeContextCollection (mongo assertion exception)"); reqSemGive(__FUNCTION__, "ngsi10 update subscription request (mongo assertion exception)"); responseP->subscribeError.errorCode.fill(SccContextElementNotFound); LM_W(("Bad Input (invalid OID format)")); return SccOk; } catch (const DBException &e) { mongoSemGive(__FUNCTION__, "findOne in SubscribeContextCollection (mongo db exception)"); reqSemGive(__FUNCTION__, "ngsi10 update subscription request (mongo db exception)"); responseP->subscribeError.errorCode.fill(SccReceiverInternalError, std::string("collection: ") + getSubscribeContextCollectionName(tenant).c_str() + " - findOne() _id: " + requestP->subscriptionId.get() + " - exception: " + e.what()); LM_E(("Database Error (%s)", responseP->subscribeError.errorCode.details.c_str())); return SccOk; } catch (...) { mongoSemGive(__FUNCTION__, "findOne in SubscribeContextCollection (mongo generic exception)"); reqSemGive(__FUNCTION__, "ngsi10 update subscription request (mongo generic exception)"); responseP->subscribeError.errorCode.fill(SccReceiverInternalError, std::string("collection: ") + getSubscribeContextCollectionName(tenant).c_str() + " - findOne() _id: " + requestP->subscriptionId.get() + " - exception: " + "generic"); LM_E(("Database Error (%s)", responseP->subscribeError.errorCode.details.c_str())); return SccOk; } if (sub.isEmpty()) { responseP->subscribeError.errorCode.fill(SccContextElementNotFound); reqSemGive(__FUNCTION__, "ngsi10 update subscription request (no subscriptions found)"); return SccOk; } /* We start with an empty BSONObjBuilder and process requestP for all the fields that can * be updated. I don't like too much this strategy (I would have preferred to start with * a copy of the original document, then modify as neded, but this doesn't seem to be easy * using the API provide by the Mongo C++ driver) * * FIXME: a better implementation strategy could be doing an findAndModify() query to do the * update, so detecting if the document was not found, instead of using findOne() + update() * with $set operation. One operations to MongoDb. vs two operations. */ BSONObjBuilder newSub; /* Entities, attribute list and reference are not updatable, so they are appended directly */ newSub.appendArray(CSUB_ENTITIES, sub.getField(CSUB_ENTITIES).Obj()); newSub.appendArray(CSUB_ATTRS, sub.getField(CSUB_ATTRS).Obj()); newSub.append(CSUB_REFERENCE, STR_FIELD(sub, CSUB_REFERENCE)); /* Duration update */ if (requestP->duration.isEmpty()) { newSub.append(CSUB_EXPIRATION, sub.getField(CSUB_EXPIRATION).numberLong()); } else { long long expiration = getCurrentTime() + requestP->duration.parse(); newSub.append(CSUB_EXPIRATION, expiration); LM_T(LmtMongo, ("New subscription expiration: %l", expiration)); } /* Restriction update */ // FIXME: Restrictions not implemented yet /* Throttling update */ if (!requestP->throttling.isEmpty()) { /* Throttling equal to 0 removes throttling */ long long throttling = requestP->throttling.parse(); if (throttling != 0) { newSub.append(CSUB_THROTTLING, throttling); } } else { /* The hasField check is needed due to Throttling could not be present in the original doc */ if (sub.hasField(CSUB_THROTTLING)) { newSub.append(CSUB_THROTTLING, sub.getField(CSUB_THROTTLING).numberLong()); } } /* Notify conditions */ bool notificationDone = false; if (requestP->notifyConditionVector.size() == 0) { newSub.appendArray(CSUB_CONDITIONS, sub.getField(CSUB_CONDITIONS).embeddedObject()); } else { /* Destroy any previous ONTIMEINTERVAL thread */ getNotifier()->destroyOntimeIntervalThreads(requestP->subscriptionId.get()); /* Build conditions array (including side-effect notifications and threads creation) * In order to do so, we have to create and EntityIdVector and AttributeList from sub * document, given the processConditionVector() signature */ EntityIdVector enV = subToEntityIdVector(sub); AttributeList attrL = subToAttributeList(sub); BSONArray conds = processConditionVector(&requestP->notifyConditionVector, enV, attrL, requestP->subscriptionId.get(), C_STR_FIELD(sub, CSUB_REFERENCE), ¬ificationDone, inFormat, tenant); newSub.appendArray(CSUB_CONDITIONS, conds); /* Remove EntityIdVector and AttributeList dynamic memory */ enV.release(); attrL.release(); } int count = sub.hasField(CSUB_COUNT) ? sub.getIntField(CSUB_COUNT) : 0; /* Last notification */ if (notificationDone) { newSub.append(CSUB_LASTNOTIFICATION, getCurrentTime()); newSub.append(CSUB_COUNT, count + 1); } else { /* The hasField check is needed due to lastNotification/count could not be present in the original doc */ if (sub.hasField(CSUB_LASTNOTIFICATION)) { newSub.append(CSUB_LASTNOTIFICATION, sub.getIntField(CSUB_LASTNOTIFICATION)); } if (sub.hasField(CSUB_COUNT)) { newSub.append(CSUB_COUNT, count); } } /* Adding format to use in notifications */ newSub.append(CSUB_FORMAT, std::string(formatToString(inFormat))); /* Update document in MongoDB */ BSONObj update = newSub.obj(); try { LM_T(LmtMongo, ("update() in '%s' collection _id '%s': %s}", getSubscribeContextCollectionName(tenant).c_str(), requestP->subscriptionId.get().c_str(), update.toString().c_str())); mongoSemTake(__FUNCTION__, "update in SubscribeContextCollection"); connection->update(getSubscribeContextCollectionName(tenant).c_str(), BSON("_id" << OID(requestP->subscriptionId.get())), update); mongoSemGive(__FUNCTION__, "update in SubscribeContextCollection"); LM_I(("Database Operation Successful (update _id: %s, %s)", requestP->subscriptionId.get().c_str(), update.toString().c_str())); } catch (const DBException &e) { mongoSemGive(__FUNCTION__, "update in SubscribeContextCollection (mongo db exception)"); reqSemGive(__FUNCTION__, "ngsi10 update subscription request (mongo db exception)"); responseP->subscribeError.errorCode.fill(SccReceiverInternalError, std::string("collection: ") + getSubscribeContextCollectionName(tenant).c_str() + " - update() _id: " + requestP->subscriptionId.get().c_str() + " - update() doc: " + update.toString() + " - exception: " + e.what()); LM_E(("Database Error (%s)", responseP->subscribeError.errorCode.details.c_str())); return SccOk; } catch (...) { mongoSemGive(__FUNCTION__, "update in SubscribeContextCollection (mongo generic exception)"); reqSemGive(__FUNCTION__, "ngsi10 update subscription request (mongo generic exception)"); responseP->subscribeError.errorCode.fill(SccReceiverInternalError, std::string("collection: ") + getSubscribeContextCollectionName(tenant).c_str() + " - update() _id: " + requestP->subscriptionId.get().c_str() + " - update() doc: " + update.toString() + " - exception: " + "generic"); LM_E(("Database Error (%s)", responseP->subscribeError.errorCode.details.c_str())); return SccOk; } /* Duration and throttling are optional parameters, they are only added in the case they * was used for update */ if (!requestP->duration.isEmpty()) { responseP->subscribeResponse.duration = requestP->duration; } if (!requestP->throttling.isEmpty()) { responseP->subscribeResponse.throttling = requestP->throttling; } responseP->subscribeResponse.subscriptionId = requestP->subscriptionId; reqSemGive(__FUNCTION__, "ngsi10 update subscription request"); return SccOk; }
/* **************************************************************************** * * mongoUnsubscribeContext - */ HttpStatusCode mongoUnsubscribeContext(UnsubscribeContextRequest* requestP, UnsubscribeContextResponse* responseP, const std::string& tenant) { bool reqSemTaken; std::string err; reqSemTake(__FUNCTION__, "ngsi10 unsubscribe request", SemWriteOp, &reqSemTaken); LM_T(LmtMongo, ("Unsubscribe Context")); /* No matter if success or failure, the subscriptionId in the response is always the one * in the request */ responseP->subscriptionId = requestP->subscriptionId; if (responseP->subscriptionId.get() == "") { reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request (no subscriptions found)", reqSemTaken); responseP->statusCode.fill(SccContextElementNotFound); alarmMgr.badInput(clientIp, "no subscriptionId"); return SccOk; } /* Look for document */ BSONObj sub; OID id; if (!safeGetSubId(requestP->subscriptionId, &id, &(responseP->statusCode))) { reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request (safeGetSubId fail)", reqSemTaken); if (responseP->statusCode.code == SccContextElementNotFound) { // FIXME: Doubt - invalid OID format? Or, just a subscription that was not found? std::string details = std::string("invalid OID format: '") + requestP->subscriptionId.get() + "'"; alarmMgr.badInput(clientIp, details); } else // SccReceiverInternalError { LM_E(("Runtime Error (exception getting OID: %s)", responseP->statusCode.details.c_str())); } return SccOk; } if (!collectionFindOne(getSubscribeContextCollectionName(tenant), BSON("_id" << id), &sub, &err)) { reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request (mongo db exception)", reqSemTaken); responseP->statusCode.fill(SccReceiverInternalError, err); return SccOk; } if (sub.isEmpty()) { reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request (no subscriptions found)", reqSemTaken); responseP->statusCode.fill(SccContextElementNotFound, std::string("subscriptionId: /") + requestP->subscriptionId.get() + "/"); return SccOk; } /* Remove document in MongoDB */ // FIXME: I would prefer to do the find and remove in a single operation. Is there something similar // to findAndModify for this? if (!collectionRemove(getSubscribeContextCollectionName(tenant), BSON("_id" << OID(requestP->subscriptionId.get())), &err)) { reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request (mongo db exception)", reqSemTaken); responseP->statusCode.fill(SccReceiverInternalError, err); return SccOk; } /* Destroy any previous ONTIMEINTERVAL thread */ getNotifier()->destroyOntimeIntervalThreads(requestP->subscriptionId.get()); // // Removing subscription from mongo subscription cache // LM_T(LmtSubCache, ("removing subscription '%s' (tenant '%s') from mongo subscription cache", requestP->subscriptionId.get().c_str(), tenant.c_str())); cacheSemTake(__FUNCTION__, "Removing subscription from cache"); CachedSubscription* cSubP = subCacheItemLookup(tenant.c_str(), requestP->subscriptionId.get().c_str()); if (cSubP != NULL) { subCacheItemRemove(cSubP); } cacheSemGive(__FUNCTION__, "Removing subscription from cache"); reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request", reqSemTaken); responseP->statusCode.fill(SccOk); return SccOk; }
/* **************************************************************************** * * mongoUnsubscribeContext - */ HttpStatusCode mongoUnsubscribeContext(UnsubscribeContextRequest* requestP, UnsubscribeContextResponse* responseP) { /* Take semaphore. The LM_S* family of macros combines semaphore release with return */ semTake(); LM_T(LmtMongo, ("Unsubscribe Context")); DBClientConnection* connection = getMongoConnection(); /* No matter if success or failure, the subscriptionId in the response is always the one * in the request */ responseP->subscriptionId = requestP->subscriptionId; /* Look for document */ BSONObj sub; try { OID id = OID(requestP->subscriptionId.get()); LM_T(LmtMongo, ("findOne() in '%s' collection _id '%s'}", getSubscribeContextCollectionName(), requestP->subscriptionId.get().c_str())); sub = connection->findOne(getSubscribeContextCollectionName(), BSON("_id" << id)); if (sub.isEmpty()) { responseP->statusCode.fill(SccContextElementNotFound, std::string("subscriptionId: '") + requestP->subscriptionId.get() + "'"); LM_SR(SccOk); } } catch( const AssertionException &e ) { /* This happens when OID format is wrong */ // FIXME: this checking should be done at parsing stage, without progressing to // mongoBackend. By the moment we can live this here, but we should remove in the future // (old issue #95) responseP->statusCode.fill(SccContextElementNotFound); LM_SR(SccOk); } catch( const DBException &e ) { responseP->statusCode.fill(SccReceiverInternalError, std::string("collection: ") + getSubscribeContextCollectionName() + " - findOne() _id: " + requestP->subscriptionId.get() + " - exception: " + e.what()); LM_SR(SccOk); } /* Remove document in MongoDB */ // FIXME: I will prefer to do the find and remove in a single operation. Is the some similar // to findAndModify for this? try { LM_T(LmtMongo, ("remove() in '%s' collection _id '%s'}", getSubscribeContextCollectionName(), requestP->subscriptionId.get().c_str())); connection->remove(getSubscribeContextCollectionName(), BSON("_id" << OID(requestP->subscriptionId.get()))); } catch( const DBException &e ) { responseP->statusCode.fill(SccReceiverInternalError, std::string("collection: ") + getSubscribeContextCollectionName() + " - remove() _id: " + requestP->subscriptionId.get().c_str() + " - exception: " + e.what()); LM_SR(SccOk); } /* Destroy any previous ONTIMEINTERVAL thread */ getNotifier()->destroyOntimeIntervalThreads(requestP->subscriptionId.get()); responseP->statusCode.fill(SccOk); LM_SR(SccOk); }
static int32_t I2C_SendRequest(LPCUSBSIO_I2C_Ctrl_t *dev, uint8_t req, uint8_t* dataOut, uint32_t dataOutLen, uint8_t* dataIn, uint32_t dataInLen) { int32_t res = 0; static uint32_t ReqIndice = 0x00; STATUS lMapStatus = SUCCESS; uint8_t outPacket[HID_I2C_PACKET_SZ + 1]; HID_I2C_OUT_REPORT_T *pOut; LPCUSBSIO_Request_t lRequest; uint32_t pos = 0x00; uint32_t offset = HID_I2C_HEADER_SZ + 1; lRequest.outPacket = dataOut; lRequest.outPacketLen = dataOutLen; lRequest.inPacket = dataIn; lRequest.inPacketLen = dataInLen; lRequest.status = LPCUSBSIO_OK; pOut = (HID_I2C_OUT_REPORT_T *) &outPacket[1]; pOut->sesId = dev->sesionId; pOut->transId = lRequest.transId = ReqIndice++; pOut->req = req; pOut->length = HID_I2C_HEADER_SZ + dataOutLen; framework_LockMutex(dev->RequestMapLock); lMapStatus = map_add(dev->request_map, (void*) (intptr_t) lRequest.transId, (void*) &lRequest); framework_UnlockMutex(dev->RequestMapLock); if(SUCCESS == lMapStatus) { //framework_CreateMutex(&lRequest.notifier); lRequest.notifier = getNotifier(dev); framework_LockMutex(lRequest.notifier); framework_LockMutex(dev->SendLock); //do //{ outPacket[0] = 0; if(lRequest.outPacket != NULL) memcpy(&outPacket[offset], lRequest.outPacket + pos, HID_I2C_PACKET_SZ + 1 - offset); res = hid_write(dev->hidDev, outPacket, HID_I2C_PACKET_SZ + 1); // if (HID_I2C_PACKET_SZ + 1 == res) // { // pos += HID_I2C_PACKET_SZ - offset + 1; // offset = 0x01; // } //} while (pos < len); framework_UnlockMutex(dev->SendLock); if(0x00 < res) { framework_WaitMutex(lRequest.notifier, 0); framework_UnlockMutex(lRequest.notifier); res = lRequest.status; } else { framework_UnlockMutex(lRequest.notifier); res = LPCUSBSIO_ERR_HID_LIB; } framework_LockMutex(dev->RequestMapLock); map_remove(dev->request_map, (void*) (intptr_t) lRequest.transId); framework_UnlockMutex(dev->RequestMapLock); FreeNotifier(dev, lRequest.notifier); //framework_DeleteMutex(lRequest.notifier); lRequest.notifier = NULL; } else { res = LPCUSBSIO_ERR_HID_LIB; } return res; }
/* **************************************************************************** * * mongoUnsubscribeContext - */ HttpStatusCode mongoUnsubscribeContext(UnsubscribeContextRequest* requestP, UnsubscribeContextResponse* responseP, const std::string& tenant) { bool reqSemTaken; std::string err; reqSemTake(__FUNCTION__, "ngsi10 unsubscribe request", SemWriteOp, &reqSemTaken); LM_T(LmtMongo, ("Unsubscribe Context")); /* No matter if success or failure, the subscriptionId in the response is always the one * in the request */ responseP->subscriptionId = requestP->subscriptionId; if (responseP->subscriptionId.get() == "") { responseP->statusCode.fill(SccContextElementNotFound); LM_W(("Bad Input (no subscriptionId)")); return SccOk; } /* Look for document */ BSONObj sub; OID id; try { id = OID(requestP->subscriptionId.get()); } catch (const AssertionException &e) { reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request (mongo assertion exception)", reqSemTaken); // // This happens when OID format is wrong // FIXME: this checking should be done at parsing stage, without progressing to // mongoBackend. For the moment we can live this here, but we should remove in the future // (old issue #95) // responseP->statusCode.fill(SccContextElementNotFound); LM_W(("Bad Input (invalid OID format)")); return SccOk; } if (!collectionFindOne(getSubscribeContextCollectionName(tenant), BSON("_id" << id), &sub, &err)) { reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request (mongo db exception)", reqSemTaken); responseP->statusCode.fill(SccReceiverInternalError, err); return SccOk; } if (sub.isEmpty()) { reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request (no subscriptions found)", reqSemTaken); responseP->statusCode.fill(SccContextElementNotFound, std::string("subscriptionId: /") + requestP->subscriptionId.get() + "/"); return SccOk; } /* Remove document in MongoDB */ // FIXME: I would prefer to do the find and remove in a single operation. Is there something similar // to findAndModify for this? if (!collectionRemove(getSubscribeContextCollectionName(tenant), BSON("_id" << OID(requestP->subscriptionId.get())), &err)) { reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request (mongo db exception)", reqSemTaken); responseP->statusCode.fill(SccReceiverInternalError, err); return SccOk; } /* Destroy any previous ONTIMEINTERVAL thread */ getNotifier()->destroyOntimeIntervalThreads(requestP->subscriptionId.get()); // FIXME P7: mongoSubCache stuff could be avoided if subscription is not patterned // // Removing subscription from mongo subscription cache // LM_T(LmtMongoSubCache, ("removing subscription '%s' (tenant '%s') from mongo subscription cache", requestP->subscriptionId.get().c_str(), tenant.c_str())); cacheSemTake(__FUNCTION__, "Removing subscription from cache"); CachedSubscription* cSubP = mongoSubCacheItemLookup(tenant.c_str(), requestP->subscriptionId.get().c_str()); if (cSubP != NULL) // Will only enter here if wildcard subscription { mongoSubCacheItemRemove(cSubP); } cacheSemGive(__FUNCTION__, "Removing subscription from cache"); reqSemGive(__FUNCTION__, "ngsi10 unsubscribe request", reqSemTaken); responseP->statusCode.fill(SccOk); return SccOk; }