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. * @NEKLAN: Contributed Japanese translation.
* @Ohcdh: Contributed Irish and Italian translations. * @Ohcdh: Contributed Irish and Italian translations.
* @Slavino: Contributed Slovak translation. * @Slavino: Contributed Slovak translation.
* @Zone: Contributed Turkish translation.
Copyright 2019, Geeksville Industries, LLC. GPL V3 license Copyright 2019, Geeksville Industries, LLC. GPL V3 license

Wyświetl plik

@ -35,7 +35,7 @@ android {
defaultConfig { defaultConfig {
// We have to list all translated languages here, because some of our libs have bogus languages that google play // 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) // 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 // Needed to make mapbox work inside the firebase testlab - FIXME, alas, still doesn't work
ndk { ndk {

Wyświetl plik

@ -9,6 +9,7 @@ import androidx.core.app.JobIntentService
import com.geeksville.android.Logging import com.geeksville.android.Logging
import com.geeksville.mesh.MainActivity import com.geeksville.mesh.MainActivity
import com.geeksville.mesh.R import com.geeksville.mesh.R
import com.geeksville.util.Exceptions
import com.geeksville.util.exceptionReporter import com.geeksville.util.exceptionReporter
import java.util.* import java.util.*
import java.util.zip.CRC32 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 /** Return true if we thing the firmwarte shoulde be updated
*
* @param swVer the version of the software running on the target
*/ */
fun shouldUpdate( fun shouldUpdate(
context: Context, context: Context,
swVer: String swVer: String
): Boolean { ): Boolean = try {
val curver = context.getString(R.string.cur_firmware_version) 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 // 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 (curVer > deviceVersion) && (deviceVersion >= minVer)
val needsUpdate = (curver != swVer) // true
} catch (ex: Exception) {
return needsUpdate && !isDevBuild && false // temporarily disabled because it fails occasionally 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) /** 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. * you can use it for the software update.
*/ */
fun doUpdate(context: Context, sync: SafeBluetooth, assetName: String) { 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 progress = 0
val totalSizeDesc = service.getCharacteristic(SW_UPDATE_TOTALSIZE_CHARACTER) val totalSizeDesc = service.getCharacteristic(SW_UPDATE_TOTALSIZE_CHARACTER)
val dataDesc = service.getCharacteristic(SW_UPDATE_DATA_CHARACTER) val dataDesc = service.getCharacteristic(SW_UPDATE_DATA_CHARACTER)
val crc32Desc = service.getCharacteristic(SW_UPDATE_CRC32_CHARACTER) val crc32Desc = service.getCharacteristic(SW_UPDATE_CRC32_CHARACTER)
val updateResultDesc = service.getCharacteristic(SW_UPDATE_RESULT_CHARACTER) val updateResultDesc = service.getCharacteristic(SW_UPDATE_RESULT_CHARACTER)
context.assets.open(assetName).use { firmwareStream -> context.assets.open(assetName).use { firmwareStream ->
val firmwareCrc = CRC32() val firmwareCrc = CRC32()
var firmwareNumSent = 0 var firmwareNumSent = 0
val firmwareSize = firmwareStream.available() val firmwareSize = firmwareStream.available()
// Start the update by writing the # of bytes in the image // Start the update by writing the # of bytes in the image
sync.writeCharacteristic( sync.writeCharacteristic(
totalSizeDesc, totalSizeDesc,
toNetworkByteArray(firmwareSize, BluetoothGattCharacteristic.FORMAT_UINT32) toNetworkByteArray(firmwareSize, BluetoothGattCharacteristic.FORMAT_UINT32)
) )
// Our write completed, queue up a readback // Our write completed, queue up a readback
val totalSizeReadback = sync.readCharacteristic(totalSizeDesc) val totalSizeReadback = sync.readCharacteristic(totalSizeDesc)
.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0) .getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0)
if (totalSizeReadback == 0) // FIXME - handle this case if (totalSizeReadback == 0) // FIXME - handle this case
throw Exception("Device rejected file size") throw Exception("Device rejected file size")
// Send all the blocks // Send all the blocks
while (firmwareNumSent < firmwareSize) { while (firmwareNumSent < firmwareSize) {
progress = firmwareNumSent * 100 / firmwareSize progress = firmwareNumSent * 100 / firmwareSize
debug("sending block ${progress}%") debug("sending block ${progress}%")
var blockSize = 512 - 3 // Max size MTU excluding framing var blockSize = 512 - 3 // Max size MTU excluding framing
if (blockSize > firmwareStream.available()) if (blockSize > firmwareStream.available())
blockSize = firmwareStream.available() blockSize = firmwareStream.available()
val buffer = ByteArray(blockSize) val buffer = ByteArray(blockSize)
// slightly expensive to keep reallocing this buffer, but whatever // slightly expensive to keep reallocing this buffer, but whatever
logAssert(firmwareStream.read(buffer) == blockSize) logAssert(firmwareStream.read(buffer) == blockSize)
firmwareCrc.update(buffer) firmwareCrc.update(buffer)
sync.writeCharacteristic(dataDesc, buffer) sync.writeCharacteristic(dataDesc, buffer)
firmwareNumSent += blockSize 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
} }
} catch (ex: BLEException) {
// We have finished sending all our blocks, so post the CRC so our state machine can advance progress = -3
val c = firmwareCrc.value throw ex // Unexpected BLE exception
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
} }
} }
} }

Wyświetl plik

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

Wyświetl plik

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