Merge pull request #62 from geeksville/dev

Dev
pull/66/head
Kevin Hester 2020-06-24 16:18:11 -07:00 zatwierdzone przez GitHub
commit 55dab4b1db
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
6 zmienionych plików z 165 dodań i 65 usunięć

Wyświetl plik

@ -65,6 +65,7 @@ This project is the work of volunteers:
* @NEKLAN: Contributed Japanese translation.
* @Ohcdh: Contributed Irish and Italian translations.
* @Slavino: Contributed Slovak translation.
* @Zone: Contributed Turkish translation.
Copyright 2019, Geeksville Industries, LLC. GPL V3 license

Wyświetl plik

@ -35,7 +35,7 @@ android {
defaultConfig {
// We have to list all translated languages here, because some of our libs have bogus languages that google play
// doesn't like and we need to strip them (gr)
resConfigs "cs", "de", "en", "es", "fi", "fr", "ga", "it", "ja", "nl", "ru", "sk", "sv", "zh"
resConfigs "cs", "de", "en", "es", "fi", "fr", "ga", "it", "ja", "nl", "ru", "sk", "sv", "tr", "zh"
// Needed to make mapbox work inside the firebase testlab - FIXME, alas, still doesn't work
ndk {

Wyświetl plik

@ -9,6 +9,7 @@ import androidx.core.app.JobIntentService
import com.geeksville.android.Logging
import com.geeksville.mesh.MainActivity
import com.geeksville.mesh.R
import com.geeksville.util.Exceptions
import com.geeksville.util.exceptionReporter
import java.util.*
import java.util.zip.CRC32
@ -173,21 +174,42 @@ class SoftwareUpdateService : JobIntentService(), Logging {
)
}
/**
* Convert a version string of the form 1.23.57 to a comparable integer of
* the form 12357.
*
* Or throw an exception if the string can not be parsed
*/
fun verStringToInt(s: String): Int {
// Allow 1 to two digits per match
val match =
Regex("(\\d{1,2}).(\\d{1,2}).(\\d{1,2})").find(s)
?: throw Exception("Can't parse version $s")
val (major, minor, build) = match.destructured
return major.toInt() * 1000 + minor.toInt() * 100 + build.toInt()
}
/** Return true if we thing the firmwarte shoulde be updated
*
* @param swVer the version of the software running on the target
*/
fun shouldUpdate(
context: Context,
swVer: String
): Boolean {
val curver = context.getString(R.string.cur_firmware_version)
): Boolean = try {
val curVer = verStringToInt(context.getString(R.string.cur_firmware_version))
val minVer =
verStringToInt("0.7.8") // The oldest device version with a working software update service
// If the user is running a development build we never do an automatic update
val isDevBuild = swVer.isEmpty() || swVer == "unset"
val deviceVersion =
verStringToInt(if (swVer.isEmpty() || swVer == "unset") "99.99.99" else swVer)
// FIXME, instead compare version strings carefully to see if less than
val needsUpdate = (curver != swVer)
return needsUpdate && !isDevBuild && false // temporarily disabled because it fails occasionally
(curVer > deviceVersion) && (deviceVersion >= minVer)
// true
} catch (ex: Exception) {
Exceptions.report(ex, "Error finding swupdate info")
false // If we fail parsing our update info
}
/** Return the filename this device needs to use as an update (or null if no update needed)
@ -237,71 +259,77 @@ class SoftwareUpdateService : JobIntentService(), Logging {
* you can use it for the software update.
*/
fun doUpdate(context: Context, sync: SafeBluetooth, assetName: String) {
val service = sync.gatt!!.services.find { it.uuid == SW_UPDATE_UUID }!!
try {
val g = sync.gatt!!
val service = g.services.find { it.uuid == SW_UPDATE_UUID }!!
info("Starting firmware update for $assetName")
info("Starting firmware update for $assetName")
progress = 0
val totalSizeDesc = service.getCharacteristic(SW_UPDATE_TOTALSIZE_CHARACTER)
val dataDesc = service.getCharacteristic(SW_UPDATE_DATA_CHARACTER)
val crc32Desc = service.getCharacteristic(SW_UPDATE_CRC32_CHARACTER)
val updateResultDesc = service.getCharacteristic(SW_UPDATE_RESULT_CHARACTER)
progress = 0
val totalSizeDesc = service.getCharacteristic(SW_UPDATE_TOTALSIZE_CHARACTER)
val dataDesc = service.getCharacteristic(SW_UPDATE_DATA_CHARACTER)
val crc32Desc = service.getCharacteristic(SW_UPDATE_CRC32_CHARACTER)
val updateResultDesc = service.getCharacteristic(SW_UPDATE_RESULT_CHARACTER)
context.assets.open(assetName).use { firmwareStream ->
val firmwareCrc = CRC32()
var firmwareNumSent = 0
val firmwareSize = firmwareStream.available()
context.assets.open(assetName).use { firmwareStream ->
val firmwareCrc = CRC32()
var firmwareNumSent = 0
val firmwareSize = firmwareStream.available()
// Start the update by writing the # of bytes in the image
sync.writeCharacteristic(
totalSizeDesc,
toNetworkByteArray(firmwareSize, BluetoothGattCharacteristic.FORMAT_UINT32)
)
// Start the update by writing the # of bytes in the image
sync.writeCharacteristic(
totalSizeDesc,
toNetworkByteArray(firmwareSize, BluetoothGattCharacteristic.FORMAT_UINT32)
)
// Our write completed, queue up a readback
val totalSizeReadback = sync.readCharacteristic(totalSizeDesc)
.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0)
if (totalSizeReadback == 0) // FIXME - handle this case
throw Exception("Device rejected file size")
// Our write completed, queue up a readback
val totalSizeReadback = sync.readCharacteristic(totalSizeDesc)
.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0)
if (totalSizeReadback == 0) // FIXME - handle this case
throw Exception("Device rejected file size")
// Send all the blocks
while (firmwareNumSent < firmwareSize) {
progress = firmwareNumSent * 100 / firmwareSize
debug("sending block ${progress}%")
var blockSize = 512 - 3 // Max size MTU excluding framing
// Send all the blocks
while (firmwareNumSent < firmwareSize) {
progress = firmwareNumSent * 100 / firmwareSize
debug("sending block ${progress}%")
var blockSize = 512 - 3 // Max size MTU excluding framing
if (blockSize > firmwareStream.available())
blockSize = firmwareStream.available()
val buffer = ByteArray(blockSize)
if (blockSize > firmwareStream.available())
blockSize = firmwareStream.available()
val buffer = ByteArray(blockSize)
// slightly expensive to keep reallocing this buffer, but whatever
logAssert(firmwareStream.read(buffer) == blockSize)
firmwareCrc.update(buffer)
// slightly expensive to keep reallocing this buffer, but whatever
logAssert(firmwareStream.read(buffer) == blockSize)
firmwareCrc.update(buffer)
sync.writeCharacteristic(dataDesc, buffer)
firmwareNumSent += blockSize
sync.writeCharacteristic(dataDesc, buffer)
firmwareNumSent += blockSize
}
// We have finished sending all our blocks, so post the CRC so our state machine can advance
val c = firmwareCrc.value
info("Sent all blocks, crc is $c")
sync.writeCharacteristic(
crc32Desc,
toNetworkByteArray(c.toInt(), BluetoothGattCharacteristic.FORMAT_UINT32)
)
// we just read the update result if !0 we have an error
val updateResult =
sync.readCharacteristic(updateResultDesc)
.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0)
if (updateResult != 0) {
progress = -2
throw Exception("Device update failed, reason=$updateResult")
}
// Device will now reboot
progress = -1 // success
}
// We have finished sending all our blocks, so post the CRC so our state machine can advance
val c = firmwareCrc.value
info("Sent all blocks, crc is $c")
sync.writeCharacteristic(
crc32Desc,
toNetworkByteArray(c.toInt(), BluetoothGattCharacteristic.FORMAT_UINT32)
)
// we just read the update result if !0 we have an error
val updateResult =
sync.readCharacteristic(updateResultDesc)
.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0)
if (updateResult != 0) {
progress = -2
throw Exception("Device update failed, reason=$updateResult")
}
// Device will now reboot
progress = -1 // success
} catch (ex: BLEException) {
progress = -3
throw ex // Unexpected BLE exception
}
}
}

Wyświetl plik

@ -20,9 +20,10 @@
android:id="@+id/channelNameEdit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:digits="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890- "
android:hint="@string/channel_name"
android:imeOptions="actionDone"
android:maxLength="12"
android:maxLength="11"
android:singleLine="true"
android:text="@string/unset" />
</com.google.android.material.textfield.TextInputLayout>

Wyświetl plik

@ -48,7 +48,7 @@
<string name="share">シェア</string>
<string name="disconnected">切断</string>
<string name="device_sleeping">スリープ</string>
<string name="connected_count">接続済み:%s人中%sオンライン</string>
<string name="connected_count">接続済み:%s人オンライン%s人中</string>
<string name="list_of_nodes">ネットワーク内のノードリスト</string>
<string name="update_firmware">ファームウェアアップデート</string>
<string name="connected_to">Meshtasticデバイスに接続しました。(%s)</string>

Wyświetl plik

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="action_settings">Ayarla</string>
<string name="channel_name">Kanal Adı</string>
<string name="channel_options">Kanal Seçenekleri</string>
<string name="share_button">Paylaş Düğmesi</string>
<string name="qr_code">QR kodu</string>
<string name="unset">Kaldır</string>
<string name="connection_status">Bağlantı durumu</string>
<string name="application_icon">uygulama ikonu</string>
<string name="unknown_username">Bilinmeyen kullanıcı adı</string>
<string name="user_avatar">Avatar</string>
<string name="sample_message">hey I found the cache, it is over here next to the big tiger. I\'m kinda scared.</string>
<string name="send_text">Metni Gönder</string>
<string name="warning_not_paired">Telefonu, henüz Meshtastic uyumlu bir telsiz ile eşleştirmediniz. Bir cihazla eşleştirin ve kullanıcı adınızı belirleyin lütfen.\n\nAçık kaynaklı bu uygulama şu an alfa-test\'i aşamasında, problemler görürseniz forum\'da lütfen paylaşınız: meshtastic.discourse.group.\n\nDaha fazla bilgi için internet sitemizi ziyaret ediniz - www.meshtastic.org.</string>
<string name="username_unset">Kullanıcı adını kaldır</string>
<string name="your_name">Adınız</string>
<string name="analytics_okay">Anonim kullanim istatistikleri ve hata raporları.</string>
<string name="looking_for_meshtastic_devices">Meshtastic cihazları aranıyor...</string>
<string name="requires_bluetooth">Bu cihaz bluetooth erişimi gerektiriyor. Lütfen Android ayarlarından izin veriniz.</string>
<string name="error_bluetooth">Hata - bu uygulama bluetooth gerektiriyor</string>
<string name="starting_pairing">Eşleşme başlatılıyor</string>
<string name="pairing_failed">Eşleşme başarız</string>
<string name="url_for_join">Meshtastic mesh ağına bağlanmak için adres</string>
<string name="accept">Kabul et</string>
<string name="cancel">İptal</string>
<string name="change_channel">Kanalı değiştir</string>
<string name="are_you_sure_channel">Kanalı değiştirmek istediğinize emin misiniz? Yeni kanal ayarlarını paylaşana dek tüm node\'lar ile iletişim sonlanacak.</string>
<string name="new_channel_rcvd">Yeni Kanal Adresi alındı</string>
<string name="do_you_want_switch">\'%s\' kanalına geçmek istiyor musunuz?</string>
<string name="map_not_allowed">Analitik raporları kapattınız. Harita sağlayıcımız (mapbox) ücretsiz kullanım paketi için analitik raporları gerektiriyor maalesef. Bu yüzden harita görünümü pasif hale getirdik.\n\n
Haritayı görmek istiyorsanız, Ayarlar bölümünden analitik raporları aktif hale getirmeniz gerekiyor. (ayrıca, şu an bunun için uygulamayı tümüyle kapatıp yeniden açmanız gerekebilir).\n\n
Eğer mapbox için ödeme yapmamız (ya da başka bir harita sağlayıcıya geçme) konusunda ilgiliyseniz, lütfen meshtastic.discourse.group sayfasında paylaşınız.</string>
<string name="permission_missing">Gerekli bir izin eksik, Meshtastic düzgün çalışamayacak. Lütfen Android ayarlarından izni aktif hale getiriniz.</string>
<string name="radio_sleeping">Telsiz uyku durumundaydı, kanal değiştirilemedi</string>
<string name="report_bug">Hata Bildir</string>
<string name="report_a_bug">Hata Bildir</string>
<string name="report_bug_text">Hata bildirmek istediğinizden emin misiniz? Hata bildirdikten sonra, lütfen meshtastic.discourse.group sayfasında paylaşınız ki raporu bulgularınızla eşleştirebilelim.</string>
<string name="report">Bildir</string>
<string name="select_radio">Telsiz seçiniz</string>
<string name="current_pair">Şu anda %s telsizi ile eşleşmiş durumdasınız.</string>
<string name="not_paired_yet">Henüz bir telsiz ile eşleşmediniz.</string>
<string name="change_radio">Telsizi değiştir</string>
<string name="please_pair">Cihazı Android ayarlarında eşleştiriniz lütfen.</string>
<string name="pairing_completed">Eşleşme tamamlandı, servis başlatılıyor</string>
<string name="pairing_failed_try_again">Eşleşme başarısız, lütfen tekrar seçiniz</string>
<string name="location_disabled">Konum erişimi kapalı, konum mesh ağına paylaşılamıyor.</string>
<string name="share">Paylaş</string>
<string name="disconnected">Bağlantı sonlandı</string>
<string name="device_sleeping">Cihaz uyku durumunda</string>
<string name="connected_count">Bağlandı: %s / %s online</string>
<string name="list_of_nodes">Ağdaki node listesi</string>
<string name="update_firmware">Yazılım güncelle</string>
<string name="connected">Radyoya bağlandı</string>
<string name="connected_to">(%s) telsizine bağlandı </string>
<string name="not_connected">Bağlı değil, aşağıdan bir radyo seçiniz</string>
<string name="connected_sleeping">Telsize bağlandı, ancak uyku durumunda</string>
<string name="update_to">%s\'e güncelle</string>
<string name="app_too_old">Uygulama çok eski</string>
<string name="must_update">Uygulamayı Google Play store (ya da GitHub)\'da güncellemelisiniz. Bu telsiz ile haberleşmek için uygualama çok eski.</string>
<string name="none">Hiçbiri (kapat)</string>
<string name="modem_config_short">Kısa menzilli (ama hızlı)</string>
<string name="modem_config_medium">Orta menzilli (ama hızlı)</string>
<string name="modem_config_long">Uzun menzilli (ama yavaş)</string>
<string name="modem_config_very_long">Çok uzun menzilli (ama yavaş)</string>
<string name="modem_config_unrecognized">TANIMLANAMADI</string>
<string name="meshtastic_service_notifications">Meshtastic Servis Bildirimleri</string>
<string name="location_disabled_warning">Android ayarlarında konum servislerine izin vermelisiniz</string>
<string name="about">Hakkında</string>
</resources>