Implemented Connection with Wi-Fi Direct and IP #9
6 changed files with 171 additions and 96 deletions
|
@ -1,6 +1,6 @@
|
|||
# Better WiFi-Direct (BWD)
|
||||
# Better Wi-Fi Direct (BWD)
|
||||
|
||||
This package contain code to improve the base WiFi-Direct implementation.
|
||||
This package contain code to improve the base Wi-Fi Direct implementation.
|
||||
|
||||
The base have some issue, like an abusive usage of listener, error code and events that make using it
|
||||
very impractical.
|
||||
|
|
|
@ -18,7 +18,6 @@ import androidx.navigation.compose.rememberNavController
|
|||
import com.faraphel.tasks_valider.database.TaskDatabase
|
||||
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
@Composable
|
||||
fun CommunicationInternetSelectScreen(activity: Activity, database: TaskDatabase) {
|
||||
val controller = rememberNavController()
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package com.faraphel.tasks_valider.ui.screen.communication.connection.internet
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material3.Button
|
||||
|
@ -75,7 +73,6 @@ fun CommunicationInternetServerScreen(
|
|||
}
|
||||
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
@Composable
|
||||
fun CommunicationInternetServerContent(
|
||||
database: TaskDatabase,
|
||||
|
@ -182,12 +179,7 @@ fun CommunicationInternetServerContent(
|
|||
val session = database.sessionDao().getById(sessionId)!!
|
||||
|
||||
// TODO(Faraphel): remove, this is a test function
|
||||
Thread {
|
||||
populateSubjectSessionPersonTest(database, session)
|
||||
}.let { thread ->
|
||||
thread.start()
|
||||
thread.join()
|
||||
}
|
||||
populateSubjectSessionPersonTest(database, session)
|
||||
|
||||
// Create the server
|
||||
Log.i("room-server", "creating the server")
|
||||
|
|
|
@ -6,6 +6,7 @@ import androidx.compose.material3.Button
|
|||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
@ -15,23 +16,20 @@ import androidx.navigation.compose.NavHost
|
|||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.faraphel.tasks_valider.connectivity.bwd.BwdManager
|
||||
import com.faraphel.tasks_valider.database.TaskDatabase
|
||||
|
||||
|
||||
@Composable
|
||||
fun CommunicationWifiP2pScreen(activity: Activity) {
|
||||
fun CommunicationWifiP2pScreen(activity: Activity, database: TaskDatabase) {
|
||||
val controller = rememberNavController()
|
||||
|
||||
var bwdManager: BwdManager? = null
|
||||
|
||||
LaunchedEffect(true) {
|
||||
// start the BWD manager
|
||||
bwdManager = BwdManager.fromActivity(activity)
|
||||
}
|
||||
// create the Wi-Fi Direct manager
|
||||
val bwdManager = remember { BwdManager.fromActivity(activity) }
|
||||
|
||||
NavHost(navController = controller, startDestination = "mode") {
|
||||
composable("mode") { CommunicationWifiP2pSelectContent(controller) }
|
||||
// composable("client") { CommunicationWifiP2pClientScreen(activity, bwdManager) }
|
||||
composable("server") { CommunicationWifiP2pServerScreen(activity, bwdManager!!) }
|
||||
composable("client") { CommunicationWifiP2pClientScreen(activity, bwdManager) }
|
||||
composable("server") { CommunicationWifiP2pServerScreen(activity, database, bwdManager) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,72 @@
|
|||
package com.faraphel.tasks_valider.ui.screen.communication.connection.wifiP2p
|
||||
|
||||
import android.app.Activity
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.faraphel.tasks_valider.connectivity.bwd.BwdManager
|
||||
import com.faraphel.tasks_valider.connectivity.task.TaskClient
|
||||
import com.faraphel.tasks_valider.connectivity.task.TaskServer
|
||||
import com.faraphel.tasks_valider.database.TaskDatabase
|
||||
import com.faraphel.tasks_valider.database.entities.ClassEntity
|
||||
import com.faraphel.tasks_valider.database.entities.PersonEntity
|
||||
import com.faraphel.tasks_valider.database.entities.SessionEntity
|
||||
import com.faraphel.tasks_valider.database.populateSubjectSessionPersonTest
|
||||
import com.faraphel.tasks_valider.ui.screen.communication.DEFAULT_SERVER_PORT
|
||||
import com.faraphel.tasks_valider.ui.screen.communication.RANGE_SERVER_PORT
|
||||
import com.faraphel.tasks_valider.ui.screen.communication.authentication.AuthenticationServerScreen
|
||||
import com.faraphel.tasks_valider.ui.screen.communication.connection.internet.CommunicationInternetServerContent
|
||||
import com.faraphel.tasks_valider.ui.screen.task.TaskSessionController
|
||||
import java.time.Instant
|
||||
|
||||
|
||||
@Composable
|
||||
fun CommunicationWifiP2pServerScreen(activity: Activity, bwdManager: BwdManager) {
|
||||
fun CommunicationWifiP2pServerScreen(
|
||||
activity: Activity,
|
||||
database: TaskDatabase,
|
||||
bwdManager: BwdManager
|
||||
) {
|
||||
val controller = rememberNavController()
|
||||
|
||||
val adminPersonEntityRaw = remember { mutableStateOf<PersonEntity?>(null) }
|
||||
val adminPersonEntity = remember { mutableStateOf<PersonEntity?>(null) }
|
||||
val client = remember { mutableStateOf<TaskClient?>(null) }
|
||||
|
||||
NavHost(navController = controller, startDestination = "authentication") {
|
||||
composable("authentication") {
|
||||
// if the admin person is not created, prompt the user for the admin information
|
||||
if (adminPersonEntityRaw.value == null) AuthenticationServerScreen(adminPersonEntityRaw)
|
||||
else controller.navigate("configuration")
|
||||
}
|
||||
composable("configuration") {
|
||||
if (client.value == null)
|
||||
CommunicationWifiP2pServerContent(
|
||||
database,
|
||||
bwdManager,
|
||||
adminPersonEntityRaw,
|
||||
adminPersonEntity,
|
||||
client,
|
||||
)
|
||||
else controller.navigate("session")
|
||||
}
|
||||
composable("session") {
|
||||
TaskSessionController(
|
||||
activity,
|
||||
client.value!!,
|
||||
adminPersonEntity.value!!
|
||||
)
|
||||
}
|
||||
}
|
||||
// TODO(Faraphel): fix and get a user
|
||||
// if the server is not created, prompt the user for the server configuration
|
||||
// if (client.value == null) CommunicationWifiP2pServerContent(activity, bwfManager, client)
|
||||
|
@ -23,83 +77,115 @@ fun CommunicationWifiP2pServerScreen(activity: Activity, bwdManager: BwdManager)
|
|||
|
||||
@Composable
|
||||
fun CommunicationWifiP2pServerContent(
|
||||
activity: Activity,
|
||||
database: TaskDatabase,
|
||||
bwdManager: BwdManager,
|
||||
adminPersonEntityRaw: MutableState<PersonEntity?>,
|
||||
adminPersonEntity: MutableState<PersonEntity?>,
|
||||
client: MutableState<TaskClient?>
|
||||
) {
|
||||
/*
|
||||
val expandedStudentList = remember { mutableStateOf(false) }
|
||||
val serverPort = remember { mutableIntStateOf(DEFAULT_SERVER_PORT) }
|
||||
val classes = remember { mutableStateOf<List<ClassEntity>?>(null) }
|
||||
val selectedClass = remember { mutableStateOf<ClassEntity?>(null) }
|
||||
val areClassesExpanded = remember { mutableStateOf(false) }
|
||||
|
||||
Column {
|
||||
// student list
|
||||
Button(onClick = { expandedStudentList.value = !expandedStudentList.value }) {
|
||||
Text(text = "Select Students List")
|
||||
}
|
||||
DropdownMenu(
|
||||
expanded = expandedStudentList.value,
|
||||
onDismissRequest = { expandedStudentList.value = false }
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
text = { Text("ISRI") },
|
||||
onClick = {}
|
||||
)
|
||||
DropdownMenuItem(
|
||||
text = { Text("MIAGE") },
|
||||
onClick = {}
|
||||
)
|
||||
// TODO(Faraphel): student lists should be loaded from the database or a file
|
||||
}
|
||||
LaunchedEffect(true) {
|
||||
// refresh the list of classes
|
||||
Thread { refreshClasses(database, classes) }.start()
|
||||
}
|
||||
|
||||
// server port
|
||||
TextField(
|
||||
value = serverPort.intValue.toString(),
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
||||
onValueChange = { text ->
|
||||
val port = text.toInt()
|
||||
if (port in RANGE_SERVER_PORT) {
|
||||
serverPort.intValue = port
|
||||
}
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
// title
|
||||
Text(
|
||||
text = "New Session",
|
||||
fontSize = 32.sp
|
||||
)
|
||||
|
||||
Button(onClick = {
|
||||
// TODO(Faraphel): should be merged with the internet server
|
||||
// separator
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
// Reset the database | TODO(Faraphel): only for testing purpose
|
||||
activity.deleteDatabase("local")
|
||||
|
||||
// Create the database
|
||||
val database = Room.databaseBuilder(
|
||||
activity,
|
||||
TaskDatabase::class.java,
|
||||
"local"
|
||||
).build()
|
||||
|
||||
// Create the admin
|
||||
// TODO: the admin should be created from the card reader
|
||||
val adminPersonEntity = PersonEntity(
|
||||
"admin",
|
||||
"admin",
|
||||
"123456789",
|
||||
"admin",
|
||||
|
||||
)
|
||||
|
||||
// Insert the admin in the database
|
||||
database.personDao().insert(adminPersonEntity)
|
||||
|
||||
bwfManager.recreateGroup {
|
||||
// Create the server
|
||||
val server = TaskServer(serverPort.intValue, database, adminPersonEntity)
|
||||
server.start()
|
||||
|
||||
// Get the client from the server
|
||||
client.value = server.getAdminClient()
|
||||
// classes
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
// description
|
||||
Text(text = "Class", fontSize = 12.sp)
|
||||
// separator
|
||||
Spacer(modifier = Modifier.width(width = 12.dp))
|
||||
// selector
|
||||
Button(onClick = { areClassesExpanded.value = !areClassesExpanded.value }) {
|
||||
// display the selected class, if selected
|
||||
if (selectedClass.value != null) Text(text = selectedClass.value!!.name)
|
||||
else Text(text = "<Not selected>")
|
||||
}
|
||||
|
||||
// class selector
|
||||
DropdownMenu(
|
||||
expanded = areClassesExpanded.value,
|
||||
onDismissRequest = { areClassesExpanded.value = false }
|
||||
) {
|
||||
// TODO(Faraphel): student lists should be loaded from the database or a file
|
||||
classes.value?.forEach { class_ ->
|
||||
DropdownMenuItem(
|
||||
text = { Text(class_.name) },
|
||||
onClick = {
|
||||
selectedClass.value = class_
|
||||
areClassesExpanded.value = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}) {
|
||||
Text("Create")
|
||||
}
|
||||
|
||||
// check if a class is selected
|
||||
if (selectedClass.value != null)
|
||||
// button to create the server
|
||||
Button(onClick = {
|
||||
Thread { // a thread is used for networking
|
||||
// Insert the admin in the database and get its id
|
||||
val adminPersonEntityId = database.personDao().insert(adminPersonEntityRaw.value!!)
|
||||
adminPersonEntity.value = database.personDao().getById(adminPersonEntityId)!!
|
||||
|
||||
// Create a new session
|
||||
// TODO(Faraphel): name
|
||||
val sessionId = database.sessionDao().insert(
|
||||
SessionEntity(
|
||||
name="NOM",
|
||||
start= Instant.now(),
|
||||
classId=selectedClass.value!!.id,
|
||||
)
|
||||
)
|
||||
val session = database.sessionDao().getById(sessionId)!!
|
||||
|
||||
// TODO(Faraphel): remove, this is a test function
|
||||
populateSubjectSessionPersonTest(database, session)
|
||||
|
||||
// create a new Wi-Fi Direct group
|
||||
bwdManager.recreateGroup {
|
||||
// Create the server
|
||||
Log.i("room-server", "creating the server")
|
||||
val server = TaskServer(
|
||||
DEFAULT_SERVER_PORT,
|
||||
database,
|
||||
session,
|
||||
adminPersonEntity.value!!,
|
||||
)
|
||||
server.start()
|
||||
|
||||
// Get the client from the server
|
||||
client.value = server.getAdminClient()
|
||||
}
|
||||
}.start()
|
||||
}) {
|
||||
Text("Create")
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Refresh the list of classes
|
||||
*/
|
||||
fun refreshClasses(database: TaskDatabase, classes: MutableState<List<ClassEntity>?>) {
|
||||
classes.value = database.classDao().getAll()
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ fun CommunicationModeSelectionScreen(activity: Activity, database: TaskDatabase)
|
|||
CommunicationInternetSelectScreen(activity, database)
|
||||
}
|
||||
composable("wifi-p2p") {
|
||||
CommunicationWifiP2pScreen(activity)
|
||||
CommunicationWifiP2pScreen(activity, database)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue