diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c
index 0298671377948a2872c3a633e1a47bfc1764ead8..c5cebc6c47873efdaf4f8aa8dc429cf614f22e7a 100644
--- a/res/res_pjsip_t38.c
+++ b/res/res_pjsip_t38.c
@@ -453,9 +453,15 @@ static void t38_masq(void *data, int framehook_id,
 	ast_framehook_detach(new_chan, framehook_id);
 }
 
+static const struct ast_datastore_info t38_framehook_datastore = {
+	.type = "T38 framehook",
+};
+
 /*! \brief Function called to attach T.38 framehook to channel when appropriate */
 static void t38_attach_framehook(struct ast_sip_session *session)
 {
+	int framehook_id;
+	struct ast_datastore *datastore = NULL;
 	static struct ast_framehook_interface hook = {
 		.version = AST_FRAMEHOOK_INTERFACE_VERSION,
 		.event_cb = t38_framehook,
@@ -463,17 +469,38 @@ static void t38_attach_framehook(struct ast_sip_session *session)
 		.chan_breakdown_cb = t38_masq,
 	};
 
-	/* Only attach the framehook on the first outgoing INVITE or the first incoming INVITE */
-	if ((session->inv_session->state != PJSIP_INV_STATE_NULL &&
-		session->inv_session->state != PJSIP_INV_STATE_INCOMING) ||
-		!session->endpoint->media.t38.enabled) {
+	/* Only attach the framehook if t38 is enabled for the endpoint */
+	if (!session->endpoint->media.t38.enabled) {
 		return;
 	}
 
-	if (ast_framehook_attach(session->channel, &hook) < 0) {
+	/* Skip attaching the framehook if the T.38 datastore already exists for the channel */
+	ast_channel_lock(session->channel);
+	if ((datastore = ast_channel_datastore_find(session->channel, &t38_framehook_datastore, NULL))) {
+		ast_channel_unlock(session->channel);
+		return;
+	}
+	ast_channel_unlock(session->channel);
+
+	framehook_id = ast_framehook_attach(session->channel, &hook);
+	if (framehook_id < 0) {
 		ast_log(LOG_WARNING, "Could not attach T.38 Frame hook to channel, T.38 will be unavailable on '%s'\n",
 			ast_channel_name(session->channel));
+		return;
 	}
+
+	ast_channel_lock(session->channel);
+	datastore = ast_datastore_alloc(&t38_framehook_datastore, NULL);
+	if (!datastore) {
+		ast_log(LOG_ERROR, "Could not attach T.38 Frame hook to channel, T.38 will be unavailable on '%s'\n",
+			ast_channel_name(session->channel));
+		ast_framehook_detach(session->channel, framehook_id);
+		ast_channel_unlock(session->channel);
+		return;
+	}
+
+	ast_channel_datastore_add(session->channel, datastore);
+	ast_channel_unlock(session->channel);
 }
 
 /*! \brief Function called when an INVITE goes out */