diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000000000000000000000000000000000000..713686c3887249af92040d13f067198fe10ec161
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+radio2
\ No newline at end of file
diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4a53bee8cb948a6e677a1a320d0ecfbe26d4062e
--- /dev/null
+++ b/.idea/AndroidProjectSystem.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="AndroidProjectSystem">
+    <option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
index 545740a654bc72f4e98998fdfe9c657cb0248e56..2bba3d39194e864580b1a25f1a94c54852be8482 100644
--- a/.idea/deploymentTargetSelector.xml
+++ b/.idea/deploymentTargetSelector.xml
@@ -4,7 +4,7 @@
     <selectionStates>
       <SelectionState runConfigName="app">
         <option name="selectionMode" value="DROPDOWN" />
-        <DropdownSelection timestamp="2025-01-16T11:45:29.800994600Z">
+        <DropdownSelection timestamp="2025-03-24T15:09:15.860193100Z">
           <Target type="DEFAULT_BOOT">
             <handle>
               <DeviceId pluginId="PhysicalDevice" identifier="serial=R58R84SRAZX" />
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c9b1536a6bae0f38a046f0562d246adc835aed54
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,5 @@
+<project version="4">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/build/classes" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/app/src/main/java/com/example/radio2/ChatActivity.kt b/app/src/main/java/com/example/radio2/ChatActivity.kt
index 85fe89d9c8bd2c78bb11505a415e7205415ecd8f..bc253813efded2be86d7f132b7f0af35e96df72e 100644
--- a/app/src/main/java/com/example/radio2/ChatActivity.kt
+++ b/app/src/main/java/com/example/radio2/ChatActivity.kt
@@ -1,10 +1,12 @@
 package com.example.radio2
 
+import android.annotation.SuppressLint
 import android.content.*
 import android.os.*
 import android.util.Log
 import android.view.KeyEvent
 import android.view.MenuItem
+import android.view.MotionEvent
 import android.view.inputmethod.EditorInfo
 import android.widget.Button
 import android.widget.TextView
@@ -18,23 +20,27 @@ import com.example.radio2.Data.userDataStorage
 import com.example.radio2.AppDatabase
 import com.example.radio2.ChatRepository
 import com.example.radio2.service.WebSocketService
+import com.example.radio2.Rtp.AudioProcessor
+import com.example.radio2.Rtp.VoicePacketSender
 import com.google.android.material.textfield.TextInputEditText
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 import java.security.MessageDigest
 
-class ChatActivity : AppCompatActivity() {
+class ChatActivity : AppCompatActivity(), VoicePacketSender {
     private lateinit var chatRepository: ChatRepository
     private var webSocketService: WebSocketService? = null
     private lateinit var chatAdapter: ChatAdapter
     private val messages = mutableListOf<MessageTo>()
     private lateinit var recyclerView: RecyclerView
     private lateinit var messageInput: TextInputEditText
-
+    private lateinit var audioProcessor: AudioProcessor
+    private var isPttStarted = false
 
     private var chatId: Long? = null
     private var userId: Long? = null
+    private var selectedUserId: String? = null
 
     private val connection = object : ServiceConnection {
         override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
@@ -43,7 +49,6 @@ class ChatActivity : AppCompatActivity() {
             webSocketService?.setCurrentActivity(this@ChatActivity)
         }
 
-
         override fun onServiceDisconnected(name: ComponentName?) {
             webSocketService = null
         }
@@ -55,7 +60,6 @@ class ChatActivity : AppCompatActivity() {
             bindService(intent, connection, BIND_AUTO_CREATE)
         }
 
-
         loadUserData()
     }
         override fun onStop() {
@@ -63,6 +67,7 @@ class ChatActivity : AppCompatActivity() {
             unbindService(connection)
         }
 
+    @SuppressLint("ClickableViewAccessibility")
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         supportActionBar?.setDisplayHomeAsUpEnabled(true)
@@ -75,16 +80,43 @@ class ChatActivity : AppCompatActivity() {
         val userId = intent.getStringExtra("USER_ID")
         val userName = intent.getStringExtra("USER_NAME")?: "Default User"
         if (userName != null && userId != null) {
+            selectedUserId = userId
             loadChat(userId, userName)
         }
 
-
         recyclerView.layoutManager = LinearLayoutManager(this)
         chatAdapter = ChatAdapter(this, messages)
         recyclerView.adapter = chatAdapter
 
         val sendMessageButton = findViewById<Button>(R.id.button)
         val backButton = findViewById<Button>(R.id.backButton)
+        val activateVoiceButton = findViewById<Button>(R.id.activateVoice2)
+
+        audioProcessor = AudioProcessor(this, this)
+
+        activateVoiceButton.setOnTouchListener { view, event ->
+            when (event.action) {
+                MotionEvent.ACTION_DOWN -> {
+                    if (!isPttStarted) {
+                        isPttStarted = true
+                        selectedUserId?.let { userId ->
+                            webSocketService?.startPTT(userId, "User")
+                        }
+                    }
+                    audioProcessor.startRecording()
+                    true
+                }
+                MotionEvent.ACTION_UP -> {
+                    isPttStarted = false
+                    audioProcessor.stopRecording()
+                    selectedUserId?.let { userId ->
+                        webSocketService?.stopPTT(userId, "User")
+                    }
+                    true
+                }
+                else -> false
+            }
+        }
 
 
         backButton.setOnClickListener {
@@ -129,6 +161,7 @@ class ChatActivity : AppCompatActivity() {
             }
         }
     }
+
     private fun loadChat(userId: String, userName: String) {
         lifecycleScope.launch {
             // Генерация ID чата на основе имени пользователя
@@ -144,6 +177,46 @@ class ChatActivity : AppCompatActivity() {
                 chatRepository.createChat(chatId, userName)
             }
 
+            // Установка имени пользователя
+            val name = findViewById<TextView>(R.id.userName)
+            name.text = userName
+            Log.d("ChatActivity", "установлен chatId: $chatId")
+        }
+    }
+
+    private suspend fun loadMessages(chatId: Long) {
+        withContext(Dispatchers.IO) {
+            val messages = chatRepository.getMessagesForChat(chatId)
+            messages.forEach { message ->
+                addReceivedMessage(message.text) // Предполагается, что вы добавите этот метод
+            }
+        }
+    }
+
+    private fun generateChatId(userName: String): Long {
+        // Генерация хэш-значения на основе имени пользователя
+        val bytes = MessageDigest.getInstance("SHA-256").digest(userName.toByteArray())
+        return bytes.fold(0L) { acc, byte -> acc * 31 + byte }
+    }
+
+    private suspend fun getMessagesForChat() {
+        chatId?.let {
+            val messagesList = chatRepository.getMessagesForChat(it)
+            messages.clear()
+            messages.addAll(messagesList.map { msg -> MessageTo(msg.text, MessageType.RECEIVED) })
+            chatAdapter.notifyDataSetChanged()
+        }
+    }
+
+            if (chat != null) {
+                // Если чат существует, загружаем сообщения
+                loadMessages(chat.id)
+                Log.d("ChatActivity", "Успешно получен chatId: $chatId")
+            } else {
+                // Если чат не существует, создаем новый чат
+                chatRepository.createChat(chatId, userName)
+            }
+
             // Установка имени пользователя
             val name = findViewById<TextView>(R.id.userName)
             name.text = userName
@@ -197,7 +270,6 @@ class ChatActivity : AppCompatActivity() {
         }
     }
 
-
     private fun addUserMessage(message: String) {
         messages.add(MessageTo(message, MessageType.SENT))
         chatAdapter.notifyItemInserted(messages.size - 1)
@@ -205,7 +277,6 @@ class ChatActivity : AppCompatActivity() {
         messageInput.setText("")
     }
 
-
     override fun onOptionsItemSelected(item: MenuItem): Boolean {
         return when (item.itemId) {
             android.R.id.home -> {
@@ -217,10 +288,13 @@ class ChatActivity : AppCompatActivity() {
         }
     }
 
-
     fun addReceivedMessage(message: String) {
         messages.add(MessageTo(message, MessageType.RECEIVED))
         chatAdapter.notifyItemInserted(messages.size - 1)
         recyclerView.scrollToPosition(messages.size - 1)
     }
+
+    override fun sendVoicePacket(base64Str: String) {
+        webSocketService?.sendVoicePacket(base64Str)
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/example/radio2/FixDataBase.kt b/app/src/main/java/com/example/radio2/FixDataBase.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f7d9f25a5966321d027445214d15e2e42e8c51af
--- /dev/null
+++ b/app/src/main/java/com/example/radio2/FixDataBase.kt
@@ -0,0 +1,84 @@
+package com.example.radio2//package com.example.radio2
+//
+//import androidx.room.Dao
+//import androidx.room.Entity
+//import androidx.room.PrimaryKey
+//import androidx.room.ForeignKey
+//import androidx.room.Insert
+//import androidx.room.Query
+//
+//
+//@Entity(tableName = "Users")
+//data class User(
+//    @PrimaryKey val id: Long,
+//    val userName: String
+//)
+//
+//
+//@Entity(tableName = "Chats")
+//data class Chat(
+//    @PrimaryKey val id: Long,
+//    val title: String
+//)
+//
+//
+//@Entity(
+//    tableName = "Chat_members",
+//    foreignKeys = [
+//        ForeignKey(entity = Chat::class, parentColumns = ["id"], childColumns = ["chatId"]),
+//        ForeignKey(entity = User::class, parentColumns = ["id"], childColumns = ["userId"])
+//    ]
+//)
+//data class ChatMember(
+//    val chatId: Long,
+//    val userId: Long
+//)
+//
+//
+//@Entity(
+//    tableName = "Message",
+//    foreignKeys = [
+//        ForeignKey(entity = Chat::class, parentColumns = ["id"], childColumns = ["chatId"]),
+//        ForeignKey(entity = User::class, parentColumns = ["id"], childColumns = ["senderId"])
+//    ]
+//)
+//data class Message(
+//    val chatId: Long,
+//    val senderId: Long,
+//    val text: String,
+//    val timestamp: Long // Можно использовать тип Date, если вы хотите
+//)
+//interface ChatDao1 {
+//    @Insert
+//    suspend fun insertChat(chat: Chat)
+//
+//    @Query("SELECT * FROM Chats WHERE id = :chatId LIMIT 1")
+//    suspend fun getChatById(chatId: Long): Chat?
+//}
+//
+//@Dao
+//interface MessageDao {
+//    @Insert
+//    suspend fun insertMessage(message: Message)
+//
+//    @Query("SELECT * FROM Message WHERE chatId = :chatId")
+//    suspend fun getMessagesForChat(chatId: Long): List<Message>
+//}
+//
+//
+//class ChatRepository(private val db: FixDataBase) {
+//
+//    suspend fun getChatByTitle(title: String): Chat? {
+//        return db.chatDao().getChatByTitle(title)
+//    }
+//
+//    suspend fun createChat(title: String): Long {
+//        val chat = Chat(id = System.currentTimeMillis(), title = title) // Используйте текущее время как ID
+//        db.chatDao().insertChat(chat)
+//        return chat.id
+//    }
+//
+//    suspend fun getMessagesForChat(chatId: Long): List<Message> {
+//        return db.messageDao().getMessagesForChat(chatId)
+//    }
+//}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/radio2/Rtp/AlawMulaw.kt b/app/src/main/java/com/example/radio2/Rtp/AlawMulaw.kt
index b37fb74f024b68a520844e96b619c2cc7db75a9e..dd9f8dea1e983f9a4c0f84c6c7cd347881c5e6ba 100644
--- a/app/src/main/java/com/example/radio2/Rtp/AlawMulaw.kt
+++ b/app/src/main/java/com/example/radio2/Rtp/AlawMulaw.kt
@@ -1,77 +1,132 @@
-package com.example.radio2.Rtp
+package org.example.radio2.Rtp
 
-class AlawMulaw {
+object AlawMulawEncoder1 {
+    private val muLawCompressTable = shortArrayOf(
+        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+        16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+        32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+        48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+        64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+        80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+        96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+        112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+        -128, -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, -116, -115, -114, -113,
+        -112, -111, -110, -109, -108, -107, -106, -105, -104, -103, -102, -101, -100, -99, -98, -97,
+        -96, -95, -94, -93, -92, -91, -90, -89, -88, -87, -86, -85, -84, -83, -82, -81,
+        -80, -79, -78, -77, -76, -75, -74, -73, -72, -71, -70, -69, -68, -67, -66, -65,
+        -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53, -52, -51, -50, -49,
+        -48, -47, -46, -45, -44, -43, -42, -41, -40, -39, -38, -37, -36, -35, -34, -33,
+        -32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17,
+        -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1
+    )
 
-    companion object {
-        private val k = intArrayOf(
-            1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-            6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-            7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-            7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-            7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-            7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-        )
+    private val muLawDecompressTable = shortArrayOf(
+        -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
+        -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
+        -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
+        -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
+        -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
+        -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
+        -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
+        -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
+        -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
+        -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
+        -876, -844, -812, -780, -748, -716, -684, -652,
+        -620, -588, -556, -524, -492, -460, -428, -396,
+        -372, -356, -340, -324, -308, -292, -276, -260,
+        -244, -228, -212, -196, -180, -164, -148, -132,
+        -120, -112, -104, -96, -88, -80, -72, -64,
+        -56, -48, -40, -32, -24, -16, -8, 0,
+        32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
+        23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
+        15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
+        11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
+        7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
+        5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
+        3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
+        2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
+        1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
+        1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
+        876, 844, 812, 780, 748, 716, 684, 652,
+        620, 588, 556, 524, 492, 460, 428, 396,
+        372, 356, 340, 324, 308, 292, 276, 260,
+        244, 228, 212, 196, 180, 164, 148, 132,
+        120, 112, 104, 96, 88, 80, 72, 64,
+        56, 48, 40, 32, 24, 16, 8, 0
+    )
 
-        private val l = intArrayOf(
-            0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-            6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
-        )
+    // Таблицы для A-law (перенесены из companion object)
+    private val k = intArrayOf(
+        1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+    )
 
-        private val m = intArrayOf(0, 132, 396, 924, 1980, 4092, 8316, 16764)
+    private val l = intArrayOf(
+        0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
+    )
 
-        fun encodeSample(input: Int): Int {
-            var a = if (input == -32768) -32767 else input
-            val c = (a.inv() shr 8) and 128
-            if (c == 0) a *= -1
-            if (a > 32635) a = 32635
-            return if (a >= 256) {
-                val b = k[(a shr 8) and 127]
-                (b shl 4) or ((a shr (b + 3)) and 15)
-            } else {
-                a shr 4
-            } xor c xor 85
-        }
+    private val m = intArrayOf(0, 132, 396, 924, 1980, 4092, 8316, 16764)
 
-        fun decodeSample(input: Int): Int {
-            var a = input xor 85
-            val c = if (a and 128 != 0) -1 else 0
-            a = if (a and 128 != 0) a and 127 else a
-            val b = ((a and 240) shr 4) + 4
-            return -8 * if (c == 0) {
-                if (b != 4) {
-                    (1 shl b) or ((a and 15) shl (b - 4)) or (1 shl (b - 5))
-                } else {
-                    (a shl 1) or 1
-                }
-            } else {
-                if (b != 4) {
-                    -((1 shl b) or ((a and 15) shl (b - 4)) or (1 shl (b - 5)))
-                } else {
-                    -(a shl 1) - 1
-                }
-            }
-        }
+    // μ-law методы
+    fun encodeMuLaw(data: ShortArray): ByteArray {
+        return ByteArray(data.size) { encodeSampleMuLaw(data[it].toInt()).toByte() }
+    }
 
-        fun encode(input: ShortArray): ByteArray {
-            val output = ByteArray(input.size)
-            for (i in input.indices) {
-                output[i] = encodeSample(input[i].toInt()).toByte()
-            }
-            return output
-        }
+    fun decodeMuLaw(data: ByteArray): ShortArray {
+        return ShortArray(data.size) { decodeSampleMuLaw(data[it]) }
+    }
+
+    private fun encodeSampleMuLaw(a: Int): Int {
+        var a = a
+        val c = a shr 8 and 128
+        if (c != 0) a = -a
+        if (a > 32635) a = 32635
+        a += 132
+        val b = l[a shr 7 and 255]
+        return (c or (b shl 4) or (a shr (b + 3) and 15)).inv()
+    }
 
-        fun decode(input: ByteArray): IntArray {
-            val output = IntArray(input.size)
-            for (i in input.indices) {
-                output[i] = decodeSample(input[i].toInt())
-            }
-            return output
+    private fun decodeSampleMuLaw(encoded: Byte): Short {
+        val temp = encoded.toInt().inv()
+        val sign = temp and 0x80
+        val exponent = (temp shr 4) and 0x07
+        val mantissa = temp and 0x0F
+
+        var sample = (mantissa shl 4) + 0x08
+        if (exponent != 0) {
+            sample = (sample + 0x100) shl (exponent - 1)
         }
+
+        return if (sign == 0) sample.toShort() else (-sample).toShort()
+    }
+
+    // A-law методы
+    fun encodeALaw(data: ShortArray): ByteArray {
+        return ByteArray(data.size) { encodeSampleALaw(data[it].toInt()).toByte() }
+    }
+
+    private fun encodeSampleALaw(a: Int): Int {
+        var a = a
+        a = if (a == -32768) -32767 else a
+        val c = if ((a.inv() shr 8) and 128 != 0) 128 else 0
+        if (c == 0) a *= -1
+        if (a > 32635) a = 32635
+        return if (a >= 256) {
+            val b = k[a shr 8 and 127]
+            (b shl 4) or (a shr (b + 3) and 15)
+        } else {
+            a shr 4
+        } xor c xor 85
     }
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/radio2/Rtp/AudioProcessor.kt b/app/src/main/java/com/example/radio2/Rtp/AudioProcessor.kt
index 7194d87806a3d8745af5f261f571590c1f6108e1..e14a4468ce6361ceeaf947cb3a91c06f03bfcb2a 100644
--- a/app/src/main/java/com/example/radio2/Rtp/AudioProcessor.kt
+++ b/app/src/main/java/com/example/radio2/Rtp/AudioProcessor.kt
@@ -78,7 +78,7 @@ class AudioProcessor(
             val recordBufferSize = maxOf(minBufferSize, bufferSize * 2)
 
             if (ContextCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) !=
-                    android.content.pm.PackageManager.PERMISSION_GRANTED
+                android.content.pm.PackageManager.PERMISSION_GRANTED
             ) {
                 throw SecurityException("Permission RECORD_AUDIO is not granted.")
             }
diff --git a/app/src/main/java/com/example/radio2/Rtp/VoicePacketProcessor.kt b/app/src/main/java/com/example/radio2/Rtp/VoicePacketProcessor.kt
index 341c0a82c7b94aa792917bd111b7c259710dbbd7..2ac5487306c3ad33aa7a542bf7b6644b54a400c5 100644
--- a/app/src/main/java/com/example/radio2/Rtp/VoicePacketProcessor.kt
+++ b/app/src/main/java/com/example/radio2/Rtp/VoicePacketProcessor.kt
@@ -56,7 +56,6 @@ class VoicePacketProcessor {
         }
 
         val pcm = decodeMuLawToPCM(Mulaw)
-        playPcmData(pcm)
         return pcm
     }
 
diff --git a/app/src/main/java/com/example/radio2/SubscriberGroupActivity.kt b/app/src/main/java/com/example/radio2/SubscriberGroupActivity.kt
index bb4b99a5452f063b4d475026f4ae6a2bdfcb5483..cb7ebcd89d1a70abaceed1f1ef68ed334dae232b 100644
--- a/app/src/main/java/com/example/radio2/SubscriberGroupActivity.kt
+++ b/app/src/main/java/com/example/radio2/SubscriberGroupActivity.kt
@@ -165,10 +165,9 @@ class SubscriberGroupActivity : ComponentActivity(), VoicePacketSender {
         setContentView(R.layout.activity_abonents)
         enableEdgeToEdge()
         val button = findViewById<Button>(R.id.activateVoice)
-        var buttonActionCount = 0
+            var buttonActionCount = 0
         audioProcessor = AudioProcessor(this, this)
 
-
         button.setOnTouchListener { view, event ->
             when (event.action) {
                 MotionEvent.ACTION_DOWN -> {
@@ -195,6 +194,7 @@ class SubscriberGroupActivity : ComponentActivity(), VoicePacketSender {
 
 
 
+
         val recyclerViewGroup: RecyclerView = findViewById(R.id.groupsRecyclerView)
             val recyclerViewSubscriber: RecyclerView = findViewById(R.id.subscribersRecyclerView)
             recyclerViewGroup.layoutManager = LinearLayoutManager(this)
diff --git a/app/src/main/java/com/example/radio2/service/WebSocketService.kt b/app/src/main/java/com/example/radio2/service/WebSocketService.kt
index 4bce75541a61989da9ccab731c59ec424b128baa..fa067bd4241c197512b35d42f49d33316c475624 100644
--- a/app/src/main/java/com/example/radio2/service/WebSocketService.kt
+++ b/app/src/main/java/com/example/radio2/service/WebSocketService.kt
@@ -41,6 +41,9 @@ import com.example.radio2.Data.AudioConfigStorage
 import com.example.radio2.Data.DeviceData2
 import kotlinx.coroutines.delay
 import kotlinx.serialization.json.JsonArray
+import kotlinx.serialization.json.JsonObject
+import kotlinx.serialization.json.int
+import kotlinx.serialization.json.long
 import java.util.UUID
 
 class WebSocketService : Service() {
@@ -76,7 +79,7 @@ class WebSocketService : Service() {
 
     companion object {
         private const val NOTIFICATION_CHANNEL_ID = "WebSocketServiceChannel"
-        private const val NOTIFICATION_ID = 1
+        private var notificationId = 0
     }
 
     override fun onBind(intent: Intent?): IBinder {
@@ -170,37 +173,28 @@ class WebSocketService : Service() {
                         when (message) {
                             is Frame.Text -> {
                                 val serverMessage = message.readText()
+                                Log.d("WebSocketService", "Received raw message: $serverMessage")
                                 handleMessage(serverMessage)
                                 val jsonArray = Json.parseToJsonElement(serverMessage).jsonArray
 
                                 jsonArray.forEach() { message ->
                                     if (message is kotlinx.serialization.json.JsonObject) {
-                                        val messageID =
-                                            message["MessageID"]?.jsonPrimitive?.content
+                                        val messageID = message["MessageID"]?.jsonPrimitive?.content
                                         if (messageID != null) {
-                                            val handler =
-                                                messageHandlerFactory.getHandler(messageID)
+                                            Log.d("WebSocketService", "Processing message with ID: $messageID")
+                                            val handler = messageHandlerFactory.getHandler(messageID)
                                             if (handler != null) {
                                                 handler.handle(message, this)
                                             } else {
-                                                Log.w(
-                                                    "MessageHandlerFactory",
-                                                    "No handler found for MessageID: $messageID"
-                                                )
+                                                Log.w("MessageHandlerFactory", "No handler found for MessageID: $messageID")
                                             }
                                         }
-
                                     }
                                 }
                             }
-
                             is Frame.Binary -> {
-                                Log.d(
-                                    "WebSocketService",
-                                    "Received binary frame of size: ${message.data.size}"
-                                )
+                                Log.d("WebSocketService", "Received binary frame of size: ${message.data.size}")
                             }
-
                             else -> Log.w("WebSocketService", "Unhandled frame: $message")
                         }
                     }
@@ -208,15 +202,15 @@ class WebSocketService : Service() {
             } catch (e: Exception) {
                 isConnected = false
                 Log.e("WebSocketService", "Error connecting WebSocket: ${e.message}")
-                /*retryConnection(url)*/
             }
         }
     }
 
     private fun handleMessage(message: String) {
-        Log.d("WebSocketService", "Received: $message")
+        Log.d("WebSocketService", "handleMessage called with: $message")
         messageCallback?.invoke(message)
         showNotification(message)
+        Log.d("WebSocketService", "handleMessage completed")
     }
 
     fun disconnectWebSocket() {
@@ -234,7 +228,7 @@ class WebSocketService : Service() {
             .setSmallIcon(android.R.drawable.stat_notify_sync)
             .build()
 
-        startForeground(NOTIFICATION_ID, notification)
+        startForeground(notificationId, notification)
     }
 
     private fun createNotificationChannel() {
@@ -431,27 +425,63 @@ class WebSocketService : Service() {
     }
 
     private fun showNotification(message: String) {
-        val notificationIntent = Intent(this, SubscriberGroupActivity::class.java)
-        notificationIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
-        val pendingIntent = PendingIntent.getActivity(
-            this,
-            0,
-            notificationIntent,
-            PendingIntent.FLAG_IMMUTABLE
-        )
-
-        val notification = NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
-            .setContentTitle("Новое сообщение")
-            .setContentText(message)
-            .setSmallIcon(android.R.drawable.stat_notify_sync)
-            .setPriority(NotificationCompat.PRIORITY_HIGH)
-            .setContentIntent(pendingIntent)
-            .setAutoCancel(true)
-            .build()
-
-        val notificationManager =
-            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
-        notificationManager.notify(NOTIFICATION_ID, notification)
+        try {
+            Log.d("WebSocketService", "Attempting to show notification for message: $message")
+            val jsonArray = Json.parseToJsonElement(message).jsonArray
+            // Обрабатываем только первое сообщение в массиве
+            if (jsonArray.isNotEmpty()) {
+                val jsonElement = jsonArray[0]
+                if (jsonElement is JsonObject) {
+                    val messageId = jsonElement["MessageID"]?.jsonPrimitive?.content
+                    Log.d("WebSocketService", "Processing message with ID: $messageId")
+                    
+                    if (messageId == "STORAGE_JOB_REQUEST") {
+                        val fromName = jsonElement["FromName"]?.jsonPrimitive?.content
+                        val title = jsonElement["Title"]?.jsonPrimitive?.content
+                        val jobType = jsonElement["JobType"]?.jsonPrimitive?.int
+                        val jobId = jsonElement["JobID"]?.jsonPrimitive?.content
+                        val time = jsonElement["Time"]?.jsonPrimitive?.long ?: System.currentTimeMillis()
+                        val sequence = jsonElement["Sequence"]?.jsonPrimitive?.int
+
+                        if (jobId != null && sequence != null) {
+                            readMessage(jobId, sequence)
+                        }
+                        
+                        Log.d("WebSocketService", "Message details - From: $fromName, Title: $title, JobType: $jobType, JobID: $jobId")
+                        
+                        // Показываем уведомление только для текстовых сообщений (JobType = 0)
+                        if (jobType == 0 && fromName != null && title != null && jobId != null) {
+                            val notificationIntent = Intent(this, SubscriberGroupActivity::class.java)
+                            notificationIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
+                            val pendingIntent = PendingIntent.getActivity(
+                                this,
+                                0,
+                                notificationIntent,
+                                PendingIntent.FLAG_IMMUTABLE
+                            )
+
+                            val notification = NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
+                                .setContentTitle("Сообщение от $fromName")
+                                .setContentText(title)
+                                .setSmallIcon(android.R.drawable.stat_notify_sync)
+                                .setPriority(NotificationCompat.PRIORITY_HIGH)
+                                .setContentIntent(pendingIntent)
+                                .setAutoCancel(true)
+                                .build()
+
+                            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+                            val uniqueNotificationId = (time.toString() + jobId).hashCode()
+                            notificationManager.notify(uniqueNotificationId, notification)
+                            Log.d("WebSocketService", "Notification shown with ID: $uniqueNotificationId")
+                        } else {
+                            Log.d("WebSocketService", "Skipping notification - conditions not met")
+                        }
+                    }
+                }
+            }
+        } catch (e: Exception) {
+            Log.e("WebSocketService", "Error parsing notification message: ${e.message}")
+        }
     }
 
 
diff --git a/h origin working_version b/h origin working_version
new file mode 100644
index 0000000000000000000000000000000000000000..736525599ce5e07953d7ac2303a50c9bc9ef8e70
--- /dev/null
+++ b/h origin working_version	
@@ -0,0 +1,170 @@
+commit 2f3c07e875cdcf72e4984e1f25132776dba0abcc (HEAD -> working_version, origin/main, origin/HEAD, main, database)
+Author: алеша <alex288got@gmail.com>
+Date:   Thu Mar 6 14:32:22 2025 +0300
+
+    фикс кода
+
+diff --git a/app/src/main/java/com/example/radio2/ChatActivity.kt b/app/src/main/java/com/example/radio2/ChatActivity.kt
+index 0ab7dde..f3917ba 100644
+--- a/app/src/main/java/com/example/radio2/ChatActivity.kt
++++ b/app/src/main/java/com/example/radio2/ChatActivity.kt
+@@ -83,7 +83,7 @@ class ChatActivity : AppCompatActivity() {
+         if (userName != null && userId != null) {
+             loadChat(userId, userName)
+         }
+-        val sendMessageButton = findViewById<Button>(R.id.button)
++
+ 
+         recyclerView.layoutManager = LinearLayoutManager(this)
+         chatAdapter = ChatAdapter(this, messages)
+@@ -172,11 +172,32 @@ class ChatActivity : AppCompatActivity() {
+             messageInput.hint = "Enter Message"
+         }
+     }
+-
++    private fun getMessagesForChat() {
++        lifecycleScope.launch {
++            val currentUserId = userId
++            val currentChatId = chatId
++
++            if (currentUserId != null && currentChatId != null) {
++                try {
++                    val chatMessages =
++                        chatRepository.getMessagesForChat(currentChatId, currentUserId)
++                    messages.clear()
++                    messages.addAll(chatMessages.map { MessageTo(it.text, MessageType.RECEIVED) })
++                    chatAdapter.notifyDataSetChanged()
++                    recyclerView.scrollToPosition(messages.size - 1)
++                } catch (e: Exception) {
++                    Log.e("ChatActivity", "Ошибка при загрузке сообщений: ${e.message}")
++                }
++            } else {
++                Log.e("ChatActivity", "Ошибка: userId или chatId не инициализированы")
++            }
++        }
++    }
+     private fun addUserMessage(message: String) {
+         messages.add(MessageTo(message, MessageType.SENT))
+         chatAdapter.notifyItemInserted(messages.size - 1)
+         recyclerView.scrollToPosition(messages.size - 1)
++        messageInput.setText("")
+     }
+ 
+     private fun logAllUsers() {
+@@ -293,7 +314,7 @@ class ChatActivity : AppCompatActivity() {
+ 
+ 
+ //    fun addReceived1Message(message: String) {messages.add(MessageTo(message, MessageType.RECEIVED))}
+-    fun addReceivedMessage(message: String , senderName: String ) {
++    fun addReceivedMessage(message: String ) {
+ //        val selectedUserName = intent.getStringExtra("USER_NAME")?: return
+ //        Log.d("chat_prefs3", "Received message from $senderName: $message")
+     //            addReceived1Message(message)
+@@ -317,13 +338,13 @@ class ChatActivity : AppCompatActivity() {
+ 
+     }
+ //    fun addUser1Message(message: String) {messages.add(MessageTo(message, MessageType.SENT))}
+-    fun addUserMessage(message: String) {
+-
+-//        addUser1Message(message)
+-        messages.add(MessageTo(message, MessageType.SENT))
+-        chatAdapter.notifyItemInserted(messages.size - 1)
+-        recyclerView.scrollToPosition(messages.size - 1)
+-        messageInput.setText("")
++//    fun addUserMessage(message: String) {
++//
++////        addUser1Message(message)
++//        messages.add(MessageTo(message, MessageType.SENT))
++//        chatAdapter.notifyItemInserted(messages.size - 1)
++//        recyclerView.scrollToPosition(messages.size - 1)
++//        messageInput.setText("")
+ //        saveMessages()
+     }
+-}
++
+diff --git a/app/src/main/java/com/example/radio2/ChatAdapter.kt b/app/src/main/java/com/example/radio2/ChatAdapter.kt
+index 7c943f0..4ff2da8 100644
+--- a/app/src/main/java/com/example/radio2/ChatAdapter.kt
++++ b/app/src/main/java/com/example/radio2/ChatAdapter.kt
+@@ -33,16 +33,12 @@ class ChatAdapter(private val context: Context, private var items: MutableList<M
+                 holder.blocUserMessage.visibility = View.VISIBLE
+                 holder.blocReceivedMessage.visibility = View.GONE
+                 holder.userMessage.text = message.text
+-
+-
+             }
+ 
+-            MessageType.RECEIVED ->{
++            MessageType.RECEIVED -> {
+                 holder.blocUserMessage.visibility = View.GONE
+                 holder.blocReceivedMessage.visibility = View.VISIBLE
+                 holder.receivedMessage.text = message.text
+-
+-
+             }
+         }
+     }
+@@ -59,10 +55,3 @@ data class MessageTo(val text: String, val type: MessageType, )
+ enum class MessageType () {
+     SENT, RECEIVED
+ }
+-
+-
+-
+-
+-
+-
+-
+diff --git a/app/src/main/java/com/example/radio2/DataBase.kt b/app/src/main/java/com/example/radio2/DataBase.kt
+index 5b34958..fcd7af2 100644
+--- a/app/src/main/java/com/example/radio2/DataBase.kt
++++ b/app/src/main/java/com/example/radio2/DataBase.kt
+@@ -206,10 +206,14 @@ val MIGRATION_1_2 = object : Migration(1, 2) {
+ // Сама база данных
+ @Database(entities = [User::class, Chat::class, ChatMember::class, Message::class], version = 2)
+ abstract class AppDatabase : RoomDatabase() {
++    abstract fun userDao(): UserDao
++    abstract fun chatDao(): ChatDao
++    abstract fun chatMemberDao(): ChatMemberDao
+     abstract fun messageDao(): MessageDao
+ 
+     companion object {
+-        @Volatile private var INSTANCE: AppDatabase? = null
++        @Volatile
++        private var INSTANCE: AppDatabase? = null
+ 
+         fun getInstance(context: Context): AppDatabase {
+             return INSTANCE ?: synchronized(this) {
+@@ -217,9 +221,7 @@ abstract class AppDatabase : RoomDatabase() {
+                     context.applicationContext,
+                     AppDatabase::class.java,
+                     "app_database"
+-                )
+-                    .addMigrations(MIGRATION_1_2)  // Применение миграции
+-                    .build()
++                ).build()
+                 INSTANCE = instance
+                 instance
+             }
+@@ -258,7 +260,7 @@ class ChatRepository(
+             chatId
+         }
+     }
+-}
++
+ 
+     // Отправить сообщение в чат
+     suspend fun sendMessage(chatId: String, senderId: String, text: String) { // chatId и senderId теперь строки
+diff --git a/app/src/main/java/com/example/radio2/MessageHandlers.kt b/app/src/main/java/com/example/radio2/MessageHandlers.kt
+index fc04df4..138564c 100644
+--- a/app/src/main/java/com/example/radio2/MessageHandlers.kt
++++ b/app/src/main/java/com/example/radio2/MessageHandlers.kt
+@@ -250,7 +250,7 @@ class StorageJobRequestHandler(private val webSocketService: WebSocketService) :
+         webSocketService.executeWhenActivityAvailable { activity ->
+             if (activity is ChatActivity) {
+                 activity.runOnUiThread {
+-                    activity.addReceivedMessage(title.toString(), fromName.toString())
++                    activity.addReceivedMessage(title.toString(),)
+                     if (jobId != null) {
+                         webSocketService.readMessage(jobId, sequence!!)
+                     }