diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c
index 26795f70539d750ad671b23e46233b77fbea9c72..d9d9c07c76c2f75c4c7d1d0a037baa61a8561ab9 100644
--- a/coreapi/linphonecore.c
+++ b/coreapi/linphonecore.c
@@ -3617,7 +3617,7 @@ static void update_primary_contact(LinphoneCore *lc) {
 	url = linphone_address_new(lc->sip_conf.contact);
 	if (!url) {
 		ms_error("Could not parse identity contact !");
-		url = linphone_address_new("sip:unknown@unkwownhost");
+		url = linphone_address_new("sip:unknown@unknownhost");
 	}
 	linphone_core_get_local_ip(lc, AF_UNSPEC, NULL, tmp);
 	if (strcmp(tmp, "127.0.0.1") == 0 || strcmp(tmp, "::1") == 0) {
diff --git a/src/address/address.cpp b/src/address/address.cpp
index c5b5ecc602e7586d0572957a6872e6fb4972324e..c61bc9c27734a6f80d80c4b56ee3b9da15201dd7 100644
--- a/src/address/address.cpp
+++ b/src/address/address.cpp
@@ -295,7 +295,7 @@ bool Address::clean() {
 }
 
 char *Address::toStringCstr() const {
-	return isValid() ? sal_address_as_string(mImpl) : nullptr;
+	return isValid() ? sal_address_as_string(mImpl) : ms_strdup("");
 }
 
 std::string Address::toString() const {
@@ -349,7 +349,7 @@ string Address::toStringOrdered() const {
 }
 
 char *Address::asStringUriOnlyCstr() const {
-	return isValid() ? sal_address_as_string_uri_only(mImpl) : nullptr;
+	return isValid() ? sal_address_as_string_uri_only(mImpl) : ms_strdup("");
 }
 
 std::string Address::asStringUriOnly() const {
diff --git a/src/c-wrapper/api/c-chat-room.cpp b/src/c-wrapper/api/c-chat-room.cpp
index c04027b25c52dcc6530d560656abb670bae10f3a..fcd99398fcd17d7da605b5d0b468cc3cb86dac34 100644
--- a/src/c-wrapper/api/c-chat-room.cpp
+++ b/src/c-wrapper/api/c-chat-room.cpp
@@ -102,7 +102,7 @@ LinphoneCore *linphone_chat_room_get_core(const LinphoneChatRoom *cr) {
 
 const LinphoneAddress *linphone_chat_room_get_peer_address(LinphoneChatRoom *cr) {
 	const auto &address = L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getPeerAddress();
-	if (address && address->isValid()) {
+	if (address) {
 		return address->toC();
 	} else {
 		return NULL;
@@ -111,7 +111,7 @@ const LinphoneAddress *linphone_chat_room_get_peer_address(LinphoneChatRoom *cr)
 
 const LinphoneAddress *linphone_chat_room_get_local_address(LinphoneChatRoom *cr) {
 	const auto &address = L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getLocalAddress();
-	if (address && address->isValid()) {
+	if (address) {
 		return address->toC();
 	} else {
 		return NULL;
diff --git a/src/chat/chat-room/client-group-chat-room.cpp b/src/chat/chat-room/client-group-chat-room.cpp
index 2258b25b7dd390af4f46b15874c6c45c6ffe2087..c1eb4044b18833eb23c1c69de581022dc5375dbd 100644
--- a/src/chat/chat-room/client-group-chat-room.cpp
+++ b/src/chat/chat-room/client-group-chat-room.cpp
@@ -97,10 +97,10 @@ shared_ptr<CallSession> ClientGroupChatRoomPrivate::createSessionTo(const std::s
 
 shared_ptr<CallSession> ClientGroupChatRoomPrivate::createSession() {
 	L_Q();
-	const std::shared_ptr<Address> &peerAddress(q->getConferenceId().getPeerAddress());
+	const std::shared_ptr<Address> &conferenceAddress = q->getConferenceAddress();
 	shared_ptr<Participant> &focus = static_pointer_cast<RemoteConference>(q->getConference())->focus;
 	const std::shared_ptr<Address> sessionTo =
-	    (peerAddress && peerAddress->isValid()) ? peerAddress : focus->getAddress();
+	    (conferenceAddress && conferenceAddress->isValid()) ? conferenceAddress : focus->getAddress();
 	return createSessionTo(sessionTo);
 }
 
diff --git a/src/conference/conference-id.cpp b/src/conference/conference-id.cpp
index 08e543d78647bbfe8ac3401892b5b80eda92bede..1f891f1f332a703b1264c9d15d99f60dcdb2043e 100644
--- a/src/conference/conference-id.cpp
+++ b/src/conference/conference-id.cpp
@@ -30,20 +30,19 @@ LINPHONE_BEGIN_NAMESPACE
 ConferenceId::ConferenceId() {
 }
 
-ConferenceId::ConferenceId(Address &&peerAddress, Address &&localAddress) {
-	this->peerAddress = Address::create(std::move(peerAddress));
-	this->localAddress = Address::create(std::move(localAddress));
+ConferenceId::ConferenceId(Address &&pAddress, Address &&lAddress) {
+	peerAddress = Address::create(std::move(pAddress));
+	localAddress = Address::create(std::move(lAddress));
 }
 
-ConferenceId::ConferenceId(const std::shared_ptr<Address> &peerAddress,
-                           const std::shared_ptr<const Address> &localAddress) {
-	this->peerAddress = (peerAddress) ? Address::create(peerAddress->getUri()) : nullptr;
-	this->localAddress = (localAddress) ? Address::create(localAddress->getUri()) : nullptr;
+ConferenceId::ConferenceId(const std::shared_ptr<Address> &pAddress, const std::shared_ptr<const Address> &lAddress) {
+	setPeerAddress(pAddress);
+	setLocalAddress(lAddress);
 }
 
-ConferenceId::ConferenceId(const std::shared_ptr<Address> &peerAddress, const std::shared_ptr<Address> &localAddress) {
-	this->peerAddress = (peerAddress) ? Address::create(peerAddress->getUri()) : nullptr;
-	this->localAddress = (localAddress) ? Address::create(localAddress->getUri()) : nullptr;
+ConferenceId::ConferenceId(const std::shared_ptr<Address> &pAddress, const std::shared_ptr<Address> &lAddress) {
+	setPeerAddress(pAddress);
+	setLocalAddress(lAddress);
 }
 
 ConferenceId::ConferenceId(const ConferenceId &other)
@@ -51,8 +50,8 @@ ConferenceId::ConferenceId(const ConferenceId &other)
 }
 
 ConferenceId &ConferenceId::operator=(const ConferenceId &other) {
-	this->peerAddress = other.peerAddress;
-	this->localAddress = other.localAddress;
+	peerAddress = other.peerAddress;
+	localAddress = other.localAddress;
 	return *this;
 }
 
@@ -70,12 +69,12 @@ bool ConferenceId::operator<(const ConferenceId &other) const {
 	       (*peerAddress == *(other.peerAddress) && *localAddress < *(other.localAddress));
 }
 
-void ConferenceId::setPeerAddress(const std::shared_ptr<Address> &addr) {
-	peerAddress = addr;
+void ConferenceId::setPeerAddress(const std::shared_ptr<const Address> &addr) {
+	peerAddress = (addr) ? Address::create(addr->getUri()) : Address::create();
 }
 
-void ConferenceId::setLocalAddress(const std::shared_ptr<Address> &addr) {
-	localAddress = addr;
+void ConferenceId::setLocalAddress(const std::shared_ptr<const Address> &addr) {
+	localAddress = (addr) ? Address::create(addr->getUri()) : Address::create();
 }
 
 const std::shared_ptr<Address> &ConferenceId::getPeerAddress() const {
diff --git a/src/conference/conference-id.h b/src/conference/conference-id.h
index 0aa522d19637b43806b87741eea843b2b64dfe0c..4134e118ac9da52f27b5f60abe7e39e15ca476c7 100644
--- a/src/conference/conference-id.h
+++ b/src/conference/conference-id.h
@@ -53,8 +53,8 @@ public:
 	const std::shared_ptr<Address> &getPeerAddress() const;
 	const std::shared_ptr<Address> &getLocalAddress() const;
 
-	void setPeerAddress(const std::shared_ptr<Address> &addr);
-	void setLocalAddress(const std::shared_ptr<Address> &addr);
+	void setPeerAddress(const std::shared_ptr<const Address> &addr);
+	void setLocalAddress(const std::shared_ptr<const Address> &addr);
 
 	bool isValid() const;
 
diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp
index 44aac9ee1953d38138306c20ceae03dacfa4d6cf..0745bd2ef054b1d28fad304dc2b92a77f22844aa 100644
--- a/src/db/main-db.cpp
+++ b/src/db/main-db.cpp
@@ -2477,7 +2477,28 @@ void MainDbPrivate::updateSchema() {
 		                " joining_time" +
 		                dbSession.timestampType() + " DEFAULT " + dbSession.currentTimestamp() + ") " + charset;
 
-		*session << "INSERT INTO chat_room_participant_device_clone SELECT * FROM chat_room_participant_device";
+		int idx = 0;
+		//		*session << "INSERT INTO chat_room_participant_device_clone SELECT * FROM chat_room_participant_device";
+		soci::rowset<soci::row> originalParticipantDeviceRows =
+		    (session->prepare << "SELECT chat_room_participant_id, participant_device_sip_address_id, state, name, "
+		                         "joining_method, joining_time FROM chat_room_participant_device");
+		for (const auto &row : originalParticipantDeviceRows) {
+			lInfo() << __func__ << " DEBUG DEBUG clone idx " << idx;
+			idx++;
+			const auto participantId = dbSession.resolveId(row, 0);
+			const auto deviceId = dbSession.resolveId(row, 1);
+			const auto state = row.get<int>(2);
+			const auto name = row.get<string>(3, "");
+			const auto joiningMethod = row.get<int>(4);
+			const auto joiningTime = dbSession.getTime(row, 5);
+			auto joiningTimeDb = dbSession.getTimeWithSociIndicator(joiningTime);
+			*session << "INSERT INTO chat_room_participant_device_clone (chat_room_participant_id, "
+			            "participant_device_sip_address_id, state, name, joining_method, joining_time)"
+			            " VALUES (:participantId, :participantDeviceSipAddressId, :participantDeviceState, "
+			            ":participantDeviceName, :participantDeviceJoiningMethod, :participantDeviceJoiningTime)",
+			    soci::use(participantId), soci::use(deviceId), soci::use(state), soci::use(name),
+			    soci::use(joiningMethod), soci::use(joiningTimeDb.first, joiningTimeDb.second);
+		}
 
 		*session << "DROP TABLE IF EXISTS chat_room_participant_device";
 
@@ -2507,10 +2528,13 @@ void MainDbPrivate::updateSchema() {
 		                ") " +
 		                charset;
 
+		int idx2 = 0;
 		soci::rowset<soci::row> participantDeviceRows =
 		    (session->prepare << "SELECT chat_room_participant_id, participant_device_sip_address_id, state, name, "
 		                         "joining_method, joining_time FROM chat_room_participant_device_clone");
 		for (const auto &row : participantDeviceRows) {
+			lInfo() << __func__ << " DEBUG DEBUG copy from clone idx " << idx2;
+			idx2++;
 			const auto participantId = dbSession.resolveId(row, 0);
 			const auto deviceId = dbSession.resolveId(row, 1);
 			const auto state = row.get<int>(2);
@@ -2877,6 +2901,8 @@ void MainDb::init() {
 	 * The mysql backend (used server-side) doesn't support this PRAGMA.
 	 */
 
+	initCleanup();
+
 	session->begin();
 
 	try {
diff --git a/src/sal/call-op.cpp b/src/sal/call-op.cpp
index 11f7a606dd8a9e93ff025ecf13e374b53f3a20f2..6a085ebbf18601d154530d103f87fe2886740fd2 100644
--- a/src/sal/call-op.cpp
+++ b/src/sal/call-op.cpp
@@ -1005,7 +1005,10 @@ void SalCallOp::processRequestEventCb(void *userCtx, const belle_sip_request_eve
 				op->callTerminated(serverTransaction, 200, request);
 				// Call end not notified by dialog deletion because transaction can end before dialog
 			} else if ((method == "INVITE") || (isUpdate = (method == "UPDATE"))) {
-				if (isUpdate && !belle_sip_message_get_body(BELLE_SIP_MESSAGE(request))) {
+				if ((op->mState == State::Terminated) || (op->mState == State::Terminating)) {
+					// A BYE has already been sent therefore we cannot accept reINVITEs or UPDATEs anymore
+					response = op->createResponseFromRequest(request, 481);
+				} else if (isUpdate && !belle_sip_message_get_body(BELLE_SIP_MESSAGE(request))) {
 					response = op->createResponseFromRequest(request, 200);
 
 					if (op->mRoot->mSessionExpiresEnabled) {