Originally when testing our bluetooth module we didn’t in fact use our own app. We used a test app published by Adafruit, the distributor of our bluetooth module breakout. This allowed us to easily send simple commands to our arduino and test the feasibility of our system.
During this iteration we introduced our own android app. This app had the bare-bones functionality that the app would need to function. We could control the lock state with a phone, we could send and receive received signal strength indicator values and we had our basic design aesthetic nailed down.
This iteration of the app introduced two way communication between the android app and the arduino. This allows the phones indication of the lock state of the lock to be consistent with reality. The app now also changed background color to indicate the connectivity of the lock to the phone. This iteration also focused on improving our spotty bluetooth connection. After a slew of troubleshooting, we determined that inability to connect consistently was due to two main factors. The first is that in certain edge cases, the app would not continue scanning for new devices. Secondly upon disconnection, the app didn’t fully sever the connection. This led to the phone believing it had been connected to too many devices and wouldn’t continue to connect to our lock.
This final version of the app focused on bluetooth security and lock sharing. Decyphering the bluetooth security protocols available and how to implement them proved to be a serious challenge. Initially we planned on implementing a man in the middle (MITM) protection protocol. Soon we decided that realizing this protocol with the given libraries was going to be too time intensive. We then pivoted to our current security scheme. We use two layers of bluetooth security between our phone and lock. The first is a “Just Works” protocol which encrypts all communications between the phone and lock using defined bluetooth standards. The second is our proprietary call, response, pass protocol. In this protocol, upon connection to the arduino, the app pings the bluetooth module until reliable communications are established. At this point the arduino will respond with a token which denotes that the communication channel has been opened. At this point the app will send once and only once a user entered passkey to the lock to check to see if this user is authenticated with this lock. At this point if the user supplies the correct passkey, then the app will be given control of the lock state. If the user is deauthenticated the bluetooth module device name will be added to a blacklist which is cleared upon app destruction. The final version of the app also included a variety of cosmetic changes and small feature additions such as implementing vibrations upon receiving lock or unlock confirmation from the arduino and the addition of an app icon. Here is a link to our git hub repo for more indepth understanding of our code.
Our android widget has two buttons for locking/unlocking and changing mode. Every time a user click the lock button, the widget calls a function of the main activity of our app. The function toggles lock button of the app and send bluetooth lock/unlock signal to arduino board. After calling the function, the widget saves current lock and mode state into the user's local device. Then the widget loads the values again by an undate function, and changes its button icons with checking current state. The mode button of the widget works exactly the same as it except sending signal to arduino board.
If a user click the lock button in the app, then the toggles its button and send signal to arduino board. Then it saves current state values into the user's local device and calls an update function of the widget. Widget's update function loads the values and changes its button icons to meet the current state.
There were given methods for app to call update function of widget. However, when making the widget call the button-toggling functions in the app, we had to make those functions and related variables static so that the widget can call those functions directly.