Basic Kotlin , Basic Kotlin Android Development - kotlin

> 1 package com.linecorp.exam
> 2
> 3 import android.os.Bundle
> 4 import android.widget.TextView
> 5 import android.app.Activity
> 6 import android.graphics.Color
> 7 import android.view.Gravity
> 8 import android.view.View
> 9 import android.view.ViewGroup
> 10 import android.widget.BaseAdapter
> 11 import android.widget.ListView
> 12
> 13 class MainActivity : Activity() {
> 14
> 15 enum class taskstate {
> 16 todo,
> 17 done
> 18 }
> 19
> 20 var tasklist = mutableListOf<Pair<String, taskstate>>()
> 21
> 22 private lateinit var myadapter: Myadapter
> 23
> 24 override fun onCreate(savedInstanceState: Bundle?) {
> 25 super.onCreate(savedInstanceState)
> 26 setContentView(R.layout.activity_main)
> 27
> 28 myadapter = Myadapter()
> 29 val listView = findViewById<ListView>(R.id.list_view)
> 30 listView.adapter = myadapter
> 31
> 32 tasklist.clear()
> 33 var i = 0
> 34 todoRepository.instance.fetch_all().forEach { t ->
> 35 tasklist.add(i++, t)
> 36 myadapter.notifyDataSetChanged()
> 37 }
> 38 }
> 39
> 40 override fun onDestroy() {
> 41 tasklist.clear()
> 42 }
> 43
> 44 inner class Myadapter : BaseAdapter() {
> 45
> 46 private lateinit var convertView: View
> 47
> 48 override fun getCount(): Int {
> 49 return tasklist.size
> 50 }
> 51
> 52 override fun getItem(position: Int): Any {
> 53 val li = tasklist.filter { it.second == taskstate.todo } +
> 54 tasklist.filter { it.second == taskstate.done }
> 55 return li[position]
> 56 }
> 57
> 58 override fun getItemId(position: Int): Long {
> 59 return 0
> 60 }
> 61
> 62 override fun getView(position: Int, convertView: View?, container: ViewGroup?): View {
> 63 this.convertView = if (convertView == null) {
> 64 layoutInflater.inflate(R.layout.list_item, container, false)
> 65 } else {
> 66 convertView
> 67 }
> 68
> 69 val i = getItem(position) as Pair<String, taskstate>
> 70 this.convertView.findViewById<TextView>(R.id.item_label)
> 71 .apply {
> 72 when (i.second) {
> 73 taskstate.todo -> {
> 74 setText("TODO")
> 75 setBackgroundColor(Color.YELLOW)
> 76 }
> 77 else -> {
> 78 setText("DONE")
> 79 }
> 80 }
> 81 }
> 82 this.convertView.findViewById<TextView>(R.id.item_text)
> 83 .setText(i.first)
> 84
> 85 return convertView!!
> 86 }
> 87 }
> 88 }`enter code here`
This was a question I got when I appeared for an test. Unfortunately I failed :) The question was how to improve this Kotlin Android code and add necessary comments if needed. (please dont consider this line ipsum dfgsdndd gfnjfn vjfnvkf fjnvkfv vnkdkvd dndk. sds dshdsd shdahd sdiauhd basudsua saudhaus sahdsuahd ashdoahsd shdoahd ashdosahd asdhoaishd )

The problem here is you are returning total if s1<s2 while that's not the case. Even if you find one such case, that's not the end of string, you should continue processing. Instead of returning, you should increment i to i+2 as you have already processed i+1. Since you can't do such increment in between a for loop, so you will have to go with a while loop.
fun romanToInt(s: String): Int {
val map = mapOf('I' to 1, 'V' to 5, 'X' to 10, 'L' to 50, 'C' to 100, 'D' to 500, 'M' to 1000)
var total = 0
var i = 0
while (i < s.length) {
val current = map[s[i]]!!
val next = if (i != s.lastIndex) map[s[i + 1]]!! else 0
if (current >= next) {
total += current
i++
} else {
total += next - current
i += 2
}
}
return total
}

Related

Uncaught Kotlin exception: kotlin.native.IncorrectDereferenceException:

I'm still relatively new to KMM and a project I'm working on keeps yeilding this error:
Uncaught Kotlin exception: kotlin.native.IncorrectDereferenceException: illegal attempt to access non-shared dev.mrbe.haarShared.HaarSDK#abc468 from other thread
at 0 kotlinmultiplatformsharedmodule 0x00000001020909a1 kfun:kotlin.Throwable#<init>(kotlin.String?){} + 97 (/opt/buildAgent/work/c5a36d4d82b914cf/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Throwable.kt:24:56)
at 1 kotlinmultiplatformsharedmodule 0x0000000102089dad kfun:kotlin.Exception#<init>(kotlin.String?){} + 93 (/opt/buildAgent/work/c5a36d4d82b914cf/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt:23:58)
at 2 kotlinmultiplatformsharedmodule 0x0000000102089fcd kfun:kotlin.RuntimeException#<init>(kotlin.String?){} + 93 (/opt/buildAgent/work/c5a36d4d82b914cf/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt:34:58)
at 3 kotlinmultiplatformsharedmodule 0x00000001020c140d kfun:kotlin.native.IncorrectDereferenceException#<init>(kotlin.String){} + 93 (/opt/buildAgent/work/c5a36d4d82b914cf/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/Runtime.kt:31:50)
at 4 kotlinmultiplatformsharedmodule 0x00000001020c508f ThrowIllegalObjectSharingException + 623 (/opt/buildAgent/work/c5a36d4d82b914cf/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/concurrent/Internal.kt:115:11)
at 5 kotlinmultiplatformsharedmodule 0x00000001022a1b52 _ZN12_GLOBAL__N_128throwIllegalSharingExceptionEP9ObjHeader + 34
at 6 kotlinmultiplatformsharedmodule 0x00000001022a389d _ZN12_GLOBAL__N_136terminateWithIllegalSharingExceptionEP9ObjHeader + 13
at 7 kotlinmultiplatformsharedmodule 0x00000001022a39b5 _ZNK27BackRefFromAssociatedObject3refIL11ErrorPolicy3EEEP9ObjHeaderv + 133
at 8 kotlinmultiplatformsharedmodule 0x0000000102070e25 -[KotlinBase toKotlin:] + 21
at 9 kotlinmultiplatformsharedmodule 0x0000000102295058 Kotlin_ObjCExport_refFromObjC + 88
at 10 kotlinmultiplatformsharedmodule 0x0000000102040676 objc2kotlin.505 + 230
at 11 haar 0x00000001006b3181 $s4haar11MyViewModelC10addBooking7bookingySo031KotlinmultiplatformsharedmoduleF0C_tYaFTY0_ + 273 (/Users/essienedim/Desktop/HAAR /haar/haar/ContentView.swift:422:33)
at 12 libswift_Concurrency.dylib 0x00007ff833c40426 _ZN5swift34runJobInEstablishedExecutorContextEPNS_3JobE + 310
at 13 libswift_Concurrency.dylib 0x00007ff833c411bd _ZL17swift_job_runImplPN5swift3JobENS_11ExecutorRefE + 77
at 14 libdispatch.dylib 0x00000001014dfe77 _dispatch_continuation_pop + 87
at 15 libdispatch.dylib 0x00000001014def27 _dispatch_async_redirect_invoke + 997
at 16 libdispatch.dylib 0x00000001014f1e77 _dispatch_root_queue_drain + 414
at 17 libdispatch.dylib 0x00000001014f2b17 _dispatch_worker_thread2 + 278
at 18 libsystem_pthread.dylib 0x00007ff833e39f8a _pthread_wqthread + 256
at 19 libsystem_pthread.dylib 0x00007ff833e38f57 start_wqthread + 15
CoreSimulator 857.7 - Device: iPhone 14 Pro (C24AA3AD-B79D-437E-BCB7-A15C83C0F412) - Runtime: iOS 16.0 (20A360) - DeviceType: iPhone 14 Pro
(lldb)
I have seen this and some other posts on this but when I try using the freeze() method, I keep getting an Unresolved reference: freeze. I can't seem to figure out what exactly I'm doing wrong and honestly, what I should be freezing exactly.
Here's the function that seems to be triggering this Exception:
func addBooking(booking: Booking) async {
await sdk.postBooking(booking: booking)
}
The SDK class is initialise in the view model like so:
class MyViewModel: ObservableObject {
let sdk: HaarSDK
...
init(sdk: HaarSDK) {
self.sdk = sdk
...
}
}
Main View:
struct MainView: View {
#StateObject private var viewModel: MyViewModel
init() {
let sdk = HaarSDK(databaseDriverFactory: DatabaseDriverFactory())
let viewModel = MyViewModel(sdk: sdk)
_viewModel = StateObject(wrappedValue: viewModel)
}
...
}
SDK class (Kotlin):
class HaarSDK(databaseDriverFactory: DatabaseDriverFactory) {
private val database = Database(databaseDriverFactory)
private val api = HaarApi()
...
#Throws(Exception::class)
suspend fun postBooking(booking: Booking) {
api.sendBooking(booking)
}
...
}
Database:
internal class Database(databaseDriverFactory: DatabaseDriverFactory) {
private val database by lazy {
AppDatabase(databaseDriverFactory.createDriver())
}
private val dbQuery = database.appDatabaseQueries
...
}
API class:
class HaarApi {
private val httpClient = HttpClient {
install(JsonFeature) {
val json = Json { ignoreUnknownKeys = true }
serializer = KotlinxSerializer(json)
}
...
suspend fun sendBooking(booking: Booking) {
val response: HttpResponse = httpClient.post(BOOKING_ENDPOINT) {
contentType(ContentType.Application.Json)
body = booking
}
...
}

Expected ',' but got identifier

I am new in solidity and General with coding.
i use this : Truffle v5.5.21 (core: 5.5.21) ,Ganache v7.2.0,Solidity v0.5.16 (solc-js)
Node v12.22.12,Web3.js v1.7.4.
I took this error and i cant fix it. I checked more interesting information's about my project but the problem is problem...I would be grateful if I could have some help
(in terminal)
CompileError: test:/contracts/EmailRegex.sol:49:34: ParserError: Expected ',' but got identifier
cur = state(cur).func(uint c);
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.9.0;
library EmailRegex {
struct State {
bool accepts;
function (byte) internal pure returns (uint) func;
}
function state(uint id) internal pure returns (State memory) {
if (id == 1) {
return State(false, s1);
}
if (id == 2) {
return State(false, s2);
}
if (id == 3) {
return State(false, s3);
}
if (id == 4) {
return State(false, s4);
}
if (id == 5) {
return State(false, s5);
}
if (id == 6) {
return State(false, s6);
}
if (id == 7) {
return State(false, s7);
}
if (id == 8) {
return State(false, s8);
}
if (id == 9) {
return State(true, s9);
}
if (id == 10) {
return State(true, s10);
}
}
function matches(string memory input) public pure returns (bool) {
uint cur = 1;
for (uint i = 0; i < bytes(input).length; i++) {
uint8 c = uint8(bytes(input)[i]);
cur = state(cur).func(uint c);
if (cur == 0) {
return false;
}
}
return state(cur).accepts;
}
function s1(uint8 c) internal pure returns (uint) {
if (c == 37 || c == 43 || c == 45 || c == 46 || c == 57 || c >= 65 && c <= 90 || c == 95 || c >= 97 && c <= 122) {
return 2;
}
return 0;
}
function s2(uint8 c) internal pure returns (uint) {
if (c == 37 || c == 43 || c == 45 || c == 46 || c >= 48 && c <= 57 || c >= 65 && c <= 90 || c == 95 || c >= 97 && c <= 122) {
return 3;
}
if (c == 64) {
return 4;
}
return 0;
}
function s3(uint8 c) internal pure returns (uint) {
if (c == 37 || c == 43 || c == 45 || c == 46 || c >= 48 && c <= 57 || c >= 65 && c <= 90 || c == 95 || c >= 97 && c <= 122) {
return 3;
}
if (c == 64) {
return 4;
}
return 0;
}
function s4(uint8 c) internal pure returns (uint) {
if (c >= 46 && c <= 47 || c >= 48 && c <= 57 || c >= 58 && c <= 64 || c >= 65 && c <= 90 || c >= 91 && c <= 95 || c >= 97 && c <= 122) {
return 5;
}
return 0;
}
function s5(uint8 c) internal pure returns (uint) {
if (c == 46) {
return 6;
}
if (c == 47 || c >= 48 && c <= 57 || c >= 58 && c <= 64 || c >= 65 && c <= 90 || c >= 91 && c <= 95 || c >= 97 && c <= 122) {
return 7;
}
return 0;
}
function s6(uint8 c) internal pure returns (uint) {
if (c == 46) {
return 6;
}
if (c == 47 || c >= 48 && c <= 57 || c >= 58 && c <= 64 || c >= 91 && c <= 95) {
return 7;
}
if (c >= 65 && c <= 90 || c >= 97 && c <= 122) {
return 8;
}
return 0;
}
function s7(uint8 c) internal pure returns (uint) {
if (c == 46) {
return 6;
}
if (c == 47 || c >= 48 && c <= 57 || c >= 58 && c <= 64 || c >= 65 && c <= 90 || c >= 91 && c <= 95 || c >= 97 && c <= 122) {
return 7;
}
return 0;
}
function s8(uint8 c) internal pure returns (uint) {
if (c == 46) {
return 6;
}
if (c == 47 || c >= 48 && c <= 57 || c >= 58 && c <= 64 || c >= 91 && c <= 95) {
return 7;
}
if (c >= 65 && c <= 90 || c >= 97 && c <= 122) {
return 9;
}
return 0;
}
function s9(uint8 c) internal pure returns (uint) {
if (c == 46) {
return 6;
}
if (c == 47 || c >= 48 && c <= 57 || c >= 58 && c <= 64 || c >= 91 && c <= 95) {
return 7;
}
if (c >= 65 && c <= 90 || c >= 97 && c <= 122) {
return 10;
}
return 0;
}
function s10(uint8 c) internal pure returns (uint) {
if (c == 46) {
return 6;
}
if (c == 47 || c >= 48 && c <= 57 || c >= 58 && c <= 64 || c >= 91 && c <= 95) {
return 7;
}
if (c >= 65 && c <= 90 || c >= 97 && c <= 122) {
return 10;
}
return 0;
}
}
Lets see your code:
cur = state(cur).func(uint c);
You are defining the input variable inside the function parameter, you can't do that, try the following:
byte c; // remember to set the value you see fit.
cur = state(cur).func(c);
I suggest you also check the rest of your code, since for some reason, you're also defining c in this loop, and variables are only defined once, yet you can reassign its value later on.
for (uint i = 0; i < bytes(input).length; i++) {
uint8 c = uint8(bytes(input)[i]);
if (cur == 0) {
return false;
}
}
Also, the interface for the function you specified on your struct's interface has a byte type input.
struct State {
bool accepts;
function (byte) internal pure returns (uint) func;
}
But, your sX functions has a uint8 input type instead. This will also cause error's
Can't see any other issues so far, yet I haven't tried compiling it.

sigsegv compilation error of simple kotlin code

Following code generates error which looks like an error in compiler, its has nothing to do with the kotlin code, or maybe I am missing something? I have JDK error on macos and some more informative error (like pasted at the end of this post) from online compiler. How can I fix it?
Code: https://pl.kotl.in/CfdXHeDyn
import kotlin.math.pow
fun calculateNumberOfContainers(data: String): Int {
val containerSizes = mutableListOf<Int>()
data.lines().forEach { containerSizes.add(it.toInt()) }
var foundCorrect = 0
val maxSubSets = (2.0).pow(20).toULong()
for (n in 0UL until maxSubSets) {
var total = 0
for (k in 0 until 20) {
val mask = 1UL shl k
if ((mask and n) != 0UL) {
total += containerSizes[k]
if (total > 150)
break
}
}
if (total == 150)
foundCorrect++
}
return foundCorrect
}
fun runcode() {
val data =
"""
33
14
18
20
45
35
16
35
1
13
18
13
50
44
48
6
24
41
30
42
""".trimIndent()
calculateNumberOfContainers(data)
}
fun main() {
runcode()
}
Error:
Exception in thread "main" com.fasterxml.jackson.core.JsonParseException: Unexpected character ('#' (code 35)): was expecting double-quote to start field name
at [Source: (String)"{#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007fc646ef2eba, pid=1900, tid=0x00007fc6307f7700
#
# JRE version: OpenJDK Runtime Environment (8.0_201-b09) (build 1.8.0_201-b09)
# Java VM: OpenJDK 64-Bit Server VM (25.201-b09 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V [libjvm.so+0x382eba]
#
# Core dump written. Default location: /var/task/core or core.1900
#
# An error report file with more information is saved as:
# /tmp/"[truncated 195 chars]; line: 1, column: 3]
at com.fasterxml.jackson.core.JsonParser._constructError (JsonParser.java:1851)
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError (ParserMinimalBase.java:707)
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar (ParserMinimalBase.java:632)
Update:
it works with 1.4.30, fails with 1.5.21, so its a bug in compiler
I changed from Unsigned Long to Unsigned Int and problem went away, code after changes looks as follows:
https://pl.kotl.in/XedacixZK
import kotlin.math.pow
fun calculateNumberOfContainers(data: String): Int {
val containerSizes = mutableListOf<Int>()
data.lines().forEach { containerSizes.add(it.toInt()) }
var foundCorrect = 0
val maxSubSets = (2.0).pow(20).toUInt()
for (n in 0U until maxSubSets) {
var total = 0
for (k in 0 until 20) {
val mask = 1U shl k
if ((mask and n) != 0U) {
total += containerSizes[k]
if (total > 150)
break
}
}
if (total == 150)
foundCorrect++
}
return foundCorrect
}
fun runcode() {
val data =
"""
33
14
18
20
45
35
16
35
1
13
18
13
50
44
48
6
24
41
30
42
""".trimIndent()
print(calculateNumberOfContainers(data))
}
fun main() {
runcode()
}

Listener not reacting to second call

I'm trying to learn Kotlin and I'm writing code to test and confirm my understanding. In the result of the following code, I expect to see "Property age changed from 37 to 38" near the end. Why am I not seeing that.
I tried writing the increment to age as age.plus initially, but that made the same result.
package ch07.ImplementingDelegatedProperties
import java.beans.PropertyChangeSupport
import java.beans.PropertyChangeListener
open class PropertyChangeAware {
protected val changeSupport = PropertyChangeSupport(this)
fun addPropertyChangeListener(listener: PropertyChangeListener) {
changeSupport.addPropertyChangeListener(listener)
}
fun removePropertyChangeListener(listener: PropertyChangeListener) {
changeSupport.removePropertyChangeListener(listener)
}
}
class Person(
val name: String, age: Int?, salary: Int
)
: PropertyChangeAware()
{
var age: Int? = age
set(newValue) {
println("age changed")
val oldValue = field
field = newValue
changeSupport.firePropertyChange(
"age", oldValue, newValue)
}
var salary: Int = salary
set(newValue) {
val oldValue = field
field = newValue
changeSupport.firePropertyChange(
"salary", oldValue, newValue)
}
operator fun plus (older: Int) :Person {
println("age changed by operator")
val oldValue = age
val newValue = (oldValue?: 0) + older
changeSupport.firePropertyChange( // don't know why this dosn't fire repeatedly
"age", oldValue, newValue)
println("age chg by operator, $oldValue -> $newValue")
this.age = (oldValue?: 0) + older
// this._attributes = _attributes
return Person(name, age = age, salary = salary)
}
}
fun main(args: Array<String>) {
var p = Person("Dmitry", 34, 2000)
p.addPropertyChangeListener(
PropertyChangeListener { event ->
println("Property ${event.propertyName} changed " +
"from ${event.oldValue} to ${event.newValue}")
}
)
println(p.age)
p.age = 35
println(p.age.toString())
p.age = 36
println(p.age.toString())
p = p + 1
println(p.age.toString())
p = p + 1
println(p.age.toString())
p.salary = 2100
}
Actual results:
34
age changed
Property age changed from 34 to 35
35
age changed
Property age changed from 35 to 36
36
age changed by operator
Property age changed from 36 to 37
age chg by operator, 36 -> 37
age changed
Property age changed from 36 to 37
37
age changed by operator
age chg by operator, 37 -> 38
age changed
38
Expected results:
34
age changed
Property age changed from 34 to 35
35
age changed
Property age changed from 35 to 36
36
age changed by operator
Property age changed from 36 to 37
age chg by operator, 36 -> 37
age changed
Property age changed from 36 to 37
37
age changed by operator
age chg by operator, 37 -> 38
age changed
Property age changed from 37 to 38 << This line expected but not appearing
38
The problem is that, at the end of your plus function, you create a brand new Person object (which copies the name and salary and increases the age) but importantly, it has a new changeSupport object which you haven't run addPropertyChangeListener on.
It looks like PropertyChangeSupport allows you to have no listeners defined, so won't error or give you a clue that there is not listener

Arduino RFID checksum calculation and key visualization

I'm using this RFID module for Arduino Ethernet R3 and I need to retrieve from the Software Serial the card (TAG) ID that is written outside the tag.
The module's datasheet says that 14 bytes are sent to the Arduino. The first is the header, the last the footer, the 2 bytes before the footer are the checksum, and the other 10 bytes are the ASCII data that contains the tag ID.
How can I recreate the ID of the card, and control the checksum? For example with a tag that has this ID: 0013530444, the Arduino response is:
I received: 2
I received: 51
I received: 67
I received: 48
I received: 48
I received: 67
I received: 69
I received: 55
I received: 53
I received: 52
I received: 67
I received: 67
I received: 66
I received: 3
But I've no idea how to print on the screen the ID read by the Arduino. How to calculate the checksum?
http://www.seeedstudio.com/wiki/index.php?title=125Khz_RFID_module_-_UART
Can anyone help me?
Here's a walkthrough of how to calculate the checksum.
Take your card number (this is just directly quoted from your text)
I received: 2
I received: 51
I received: 67
I received: 48
I received: 48
I received: 67
I received: 69
I received: 55
I received: 53
I received: 52
I received: 67
I received: 67
I received: 66
I received: 3
This would give you a number that is equivalent to the following:
2 51 67 48 48 67 69 55 53 52 67 67 66 3
The first numer (2) indicates that this is the beginning of a request.
The last number (3) indicates that this is the end of a request.
2 51 67 48 48 67 69 55 53 52 67 67 66 3
For the purposes of calculating the checksum, we are going to remove these two numbers. So your new number is now:
51 67 48 48 67 69 55 53 52 67 67 66
The last two numbers that you have are your checksum. The remaining numbers are your card number. So:
Your card number is:
51 67 48 48 67 69 55 53 52 67
And your checksum is:
67 66
Next you need to convert your Card Number and your Checksum to ASCII values:
Your card number is:
3 C 0 0 C E 7 5 4 C
And your checksum is:
C B
Next, grab each number into pairs:
Your card number is:
3C 00 CE 75 4C
And your checksum is:
CB
Then you need to treat each pair as a HEXIDECIMAL value and do an XOR against them. So basically you need to prove the following:
3C ^ 00 ^ CE ^ 75 ^ 4C == CB
(3C ^ 00) = 3C
3C ^ CE ^ 75 ^ 4C == CB
(3C ^ CE) = F2
F2 ^ 75 ^ 4C == CB
(3C ^ CE) = 87
87 ^ 4C == CB
(87 ^ 4C) = CB
CB == CB
Because CB == CB, this is a valid transaction.
No doubt someone else can come up with a better approach than this, but there should be enough pseudo code here for you to write it yourself.
I found this blog which has an implementation in Arduino, I've adapted it to work in Java and results are good. Since there are a lot of bitwise operations - I used http://www.miniwebtool.com/bitwise-calculator/ to try to understand what's going on. I understand all of it except (val | (tempbyte << 4)), I mean I understand what the statement does, I just struggle to see how that produces the result I want.
void loop () {
byte i = 0;
byte val = 0;
byte code[6];
byte checksum = 0;
byte bytesread = 0;
byte tempbyte = 0;
if(Serial.available() > 0) {
if((val = Serial.read()) == 2) {
// check for header
bytesread = 0;
while (bytesread < 12) {
// read 10 digit code + 2 digit checksum
if( Serial.available() > 0) {
val = Serial.read();
if((val == 0x0D)||(val == 0x0A)||(val == 0x03)||(val == 0x02)) {
// if header or stop bytes before the 10 digit reading
break;
// stop reading
}
// Do Ascii/Hex conversion:
if ((val >= '0') && (val <= '9')) {
val = val - '0';
} else if ((val >= 'A') && (val <= 'F')) {
val = 10 + val - 'A';
}
// Every two hex-digits, add byte to code:
if (bytesread & 1 == 1) {
// make some space for this hex-digit by
// shifting the previous hex-digit with 4 bits to the left:
code[bytesread >> 1] = (val | (tempbyte << 4));
if (bytesread >> 1 != 5) {
// If we're at the checksum byte,
checksum ^= code[bytesread >> 1];
// Calculate the checksum... (XOR)
};
} else {
tempbyte = val;
// Store the first hex digit first...
};
bytesread++;
// ready to read next digit
}
}
// Output to Serial:
if (bytesread == 12) {
// removed code for clarity
LCD.print("Check:");
LCD.print(code[5], HEX);
LCD.print(code[5] == checksum ? "-passed" : "-error");
}
bytesread = 0;
}
}
}
My Java/Android port is listening over a BluetoothSocket. I'm using the code from BlueTerm as the base, this code goes in the ConnectedThread. Apologies for all silly comments, but I'm still learning Java).
//assume you have checksum as int and code as int array. it will overflow if bytes are used like above example
public void run() {
Log.d(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream while connected
while (true) {
Log.d(TAG, "Running");
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
for (int i = 0; i < bytes; i++) {
Log.d(TAG, "Reading: " + i + " of " + bytes + " from input stream");
byte b = buffer[i];
try {
if(bytesread >= 0) {
//just printing ASCII
char printableB = (char) b;
if (b < 32 || b > 126) printableB = ' ';
Log.d(TAG, "'" + Character.toString(printableB) + "' (" + Integer.toString(b) + ")");
if((b == 0x0D)||(b == 0x0A)||(b == 0x03)||(b == 0x02)) {
// if header or stop bytes before the 10 digit reading
Log.e(TAG, i + " Unexpected header while processing character " + Integer.toString(b));
} else {
// Do ASCII/Hex conversion
if ((b >= '0') && (b <= '9')) {
b = (byte) (b - '0');
} else if ((b >= 'A') && (b <= 'F')) {
b = (byte) (10 + b - 'A');
}
if ((bytesread & 1) == 1) {
//if isOdd(bytesread)
// make some space for this hex-digit by shifting the previous hex-digit with 4 bits to the left:
code[bytesread >> 1] = (b | (tempbyte << 4));
if (bytesread >> 1 != 5) {
// If we're not at the checksum byte,
checksum ^= code[bytesread >> 1];
// Calculate the checksum... (XOR)
}
} else {
// Store the first hex digit first
tempbyte = b;
}
}
bytesread++;
} else if(b == 2) {
bytesread = 0;
Log.d(TAG, "Header found!");
}
if(bytesread == 12) {
String check = (code[5] == checksum ? "-passed" : "-error");
String r = "";
for(int j = 0; j < 5; j++){
r += Integer.toString(code[i]);
}
Log.d(TAG, "Check:" + Integer.toString(code[5]) + check);
init();
} else if(bytesread > 12){
Log.e(TAG, "Too many bytes!");
}
} catch (Exception e) {
Log.e(TAG, i + " Exception while processing character " + Integer.toString(b), e);
}
}
String a = buffer.toString();
a = "";
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
break;
}
}
Log.i(TAG, "END mConnectedThread");
}