diff --git a/README.md b/README.md
index 4031d9b..23f3332 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,9 @@
-# at_pico_w for UMass 2022 IoT projects
+# at_pico_w
+
+For UMass 2022 IoT Projects.
# Table of Contents
@@ -17,33 +19,23 @@
- [VSCode](https://code.visualstudio.com/Download) with the [Pico-W-Go extension](https://marketplace.visualstudio.com/items?itemName=paulober.pico-w-go)
- [Git](https://git-scm.com/) and your own [GitHub](https://github.com) account
-- Two [atSigns](https://my.atsign.com/go) and their [.atKeys files](https://www.youtube.com/watch?v=2Uy-sLQdQcA&ab_channel=Atsign)
-- [FileZilla](https://filezilla-project.org/) or any other FTP software.
- A [Raspberry Pi Pico W](https://www.canakit.com/raspberry-pi-pico-w.html) and [a micro-USB to USB-A cable](https://m.media-amazon.com/images/I/61kT7kpt2hL._AC_SY450_.jpg) (to connect your Pico to your Computer)
+- [FileZilla](https://filezilla-project.org/) or any other FTP software.
+- Two [atSigns](https://my.atsign.com/go) and their [.atKeys files](https://www.youtube.com/watch?v=2Uy-sLQdQcA&ab_channel=Atsign)
# Instructions
-Hi UMass students! I've wrote some code for you to get your Pico Ws setup with the atPlatform. Big shoutout to @realvarx for developing AES CTR and RSA-2048 private key signing on the Pico W. Let me know if you have any questions on Discord (Jeremy#7970) or by email (jeremy.tubongbanua@atsign.com) or just on our [discord](https://discord.atsign.com)
+## 0. Introduction
-## Forking the Project
+Hi UMass students! I've wrote some code for you to get your Pico Ws setup with the atPlatform. Big shoutout to @realvarx on GitHub for developing AES CTR and RSA-2048 private key signing on the Pico W.
-First, let's create a fork of this repository branch on your own GitHub account. This gives you a copy of the code that you can edit on your own system.
+Let me know if you have any questions on Discord (Jeremy#7970) or by email (jeremy.tubongbanua@atsign.com) or just on our [discord](https://discord.atsign.com).
-1. Fork this repository by clicking "Fork"
-2. Go into your terminal where you like to keep your code projects and do the following:
-- `mkdir at_pico_w` (make an at_pico_w folder)
-- `cd at_pico_w` (change directories)
-- `git clone /at_pico_w.git> .` (clone your fork into the folder you've created)
-- `git checkout -b umass2022` (create a new branch called umass2022 and go into it)
-- `git reset --hard origin/umass2022` (reset the branch to the origin)
-
-Now you should have all of the code in your folder. Your folder should look something like this:
-
-
+Be sure to get the first 4 prerequisites under [Prerequisites](#prerequisites) before you start. The last 2 prerequisites (FTP software and 2 atSigns) can be done later.
-## Setting up Micropython on your Pico W
+## 1. Getting the right Micropython Firmware for your Pico W
-1. Go to [atsign-foundation/micropython/releases](https://github.com/atsign-foundation/micropython/releases) and download the `.uf2` file. This `.uf2` file is specially built firmware to allow special encryption that Atsign uses (AES CTR and RSA-2048) to work on the Pico W. Big shoutout to @realvarx for developing all the Atsign encryption for the Pico W.
+1. Go to [atsign-foundation/micropython/releases](https://github.com/atsign-foundation/micropython/releases) and download the `.uf2` file. This `.uf2` file is specially built firmware to allow a certain encryption that Atsign uses (AES-256 CTR mode) to work on the Pico W. Big shoutout to @realvarx for developing all the Atsign encryption for the Pico W.
2. Unplug your Pico W from your computer. Hold down the BOOTSEL button on the Pico W and then plug back the Pico W into your computer (all while holding down the BOOTSEL button). Once the Pico W is plugged in, you can let go of the BOOTSEL button. Your Pico W should now be in bootloader mode.
@@ -53,29 +45,35 @@ You should see the Pico on your computer as a USB drive (see image below).
3. Drag and drop the `firmware.uf2` file into the Pico W. This will flash the Pico W with the new firmware. Now the Pico W should automatically restart so no need to unplug/replug it.
-## Getting Started - Blinking the LED
+## 2. Getting Started - Blinking the LED
-1. Open the `at_pico_w` folder on VSCode.
+Now let's create our first project.
+
+1. Open VSCode and open an empty folder somewhere on your computer. This is where your project will be.
2. Get the [Pico-W-Go extension](https://marketplace.visualstudio.com/items?itemName=paulober.pico-w-go)
-3. Create a file named `blink.py` and copy and paste the following code into it:
+3. Create a file named `blink.py` and write the following code:
```py
# blink.py
+
import machine
import time
-led = machine.Pin("LED", machine.Pin.OUT)
+led = machine.Pin("LED", machine.Pin.OUT) # "LED" is the on board LED
+# blink ten times
for i in range(10):
print('Blinking... %s' %str(i+1))
led.toggle()
time.sleep(0.5)
```
+Note: You could also name it `main.py`. However, `main.py` is the default file that the Pico W will run when it starts up. But with the [Pico-W-Go extension](https://marketplace.visualstudio.com/items?itemName=paulober.pico-w-go), you can choose *when* to run a file (regardless of name) which is how we will be running our files from here on out. I recommend not having a main.py at all since it tends to bug out the Pico W trying to run your experimental code as soon as it boots which can get annoying.
+
-4. Open the command pallette via `Ctrl + Shift + P` (or `Cmd + Shift + P` if you are on a Mac) and type `Configure Project` and press Enter. The extension should setup your current folder as a Pico W project. Now, any Pico-W-Go commands should work. You can also access Pico-W-Go commands by clicking on "All Commands" at the bottom of VSCode.
+4. Open the command pallette via `Ctrl + Shift + P` (or `Cmd + Shift + P` if you are on a Mac) and type `Configure Project` and press Enter. The extension should setup your current folder as a Pico W project by initializing a `.vscode/` hidden folder and a `.picowgo` hidden file. Now, any Pico-W-Go commands should work. You can also access Pico-W-Go commands by clicking on "All Commands" at the bottom of VSCode.
VSCode bottom toolbar with Pico-W-Go commands:
@@ -85,25 +83,102 @@ VSCode bottom toolbar with Pico-W-Go commands:
7. Make sure you have your `blink.py` python file open in the editor and Run the "Run current file" command. You should see the onboard LED blink 10 times.
-## Connecting to the atPlatform
+## 3. Forking the Project
+
+Now we know your Pico W is working swell, let's get into some atPlatform.
+
+First, let's create a fork of this repository branch on your own GitHub account. This gives you a copy of the code that you can edit on your own system.
+
+1. Fork this repository by clicking "Fork"
+2. Go into your terminal where you like to keep your code projects and do the following:
+- `mkdir at_pico_w` (make an at_pico_w folder)
+- `cd at_pico_w` (change directories)
+- `git clone /at_pico_w.git> .` (clone your fork into the folder you've created)
+- `git checkout -b umass2022` (create a new branch called umass2022 and go into it)
+- `git reset --hard origin/umass2022` (reset the branch to the origin)
+
+Now you should have all of the code in your folder. Your folder should look something like this:
+
+
+
+## 4. Connecting to WiFi
+
+1. Edit the `settings.json` by adding your WiFi and Password, leave the atSign blank for now.
+
+settings.json
+
+```json
+{
+ "ssid": "********",
+ "password": "&&&&",
+ "atSign": ""
+}
+```
+
+
+2. You should see a file called `test_1_wifi.py` in your project (since you forked the repository). Open this file in VSCode and run the Pico-W-Go command "Run this current file".
+
+3. The code is:
+```py
+def main():
+ from lib.at_client import io_util
+ from lib import wifi
+
+ # Add your SSID an Password in `settings.json`
+ ssid, password, atSign = io_util.read_settings()
+ del atSign # atSign not needed in memory right now
+
+ print('\nConnecting to %s (Ctrl+C to stop)...' % ssid)
+ wlan = wifi.init_wlan(ssid, password)
+
+ if not wlan == None:
+ print('Connected to WiFi %s: %s' %(ssid, str(wlan.isconnected())))
+ else:
+ print('Failed to connect to \'%s\'... :(' %ssid)
+
+if __name__ == '__main__':
+ main()
+```
+
+4. Your output should be similar to:
+
+```
+Connecting to Soup (Ctrl+C to stop)...
+Connected to WiFi Soup: True
+```
-1. You will notice there's a `main2.py` file in your project. Running this file via the "Run current file" command will connect your Pico W to the atPlatform. But there is some setup that needs to be done first:
+## 5. Connecting to your device atSign's atServer.
-2. Edit `settings.json` by inputting your WiFi ssid, WiFi password, and the device atSign that you own and have the .atKeys to. To get an .atKeys file, go to 0:54 of this [video](https://youtu.be/2Uy-sLQdQcA?t=54). The easiest way is to download [atmospherePro](https://atsign.com/apps/atmospherepro/) on your computer (via Microsoft Store on Windows or the Appstore if you're on Mac) and onboarding your atSign via the onboarding widget in the app. There are other ways to generate the encryption .atKeys file for an atSign (such as the [at_onboarding_cli on Dart](), [RegisterCLI on Java](), the [sshnp_register_tool in at_tools](), [OnboardingCLI in Java]()) but generating it through atmospherePro is the easiest if you don't want to deal with any code.
+1. If you do not have all of the prerequisites, it is time to get them, especially: [FileZilla](https://filezilla-project.org/) or any other FTP software and two [atSigns](https://my.atsign.com/go) and their [.atKeys files](https://www.youtube.com/watch?v=2Uy-sLQdQcA&ab_channel=Atsign). Continue reading to find out how to get your .atKeys files.
-3. Run the "Start FTP server" command. You should be given an address in the terminal (similar to the image below):
+2. Add the atSign you wish your device's atSign to be in the `settings.json`. This is an atSign you own and got from [my.atsign.com/go](https://my.atsign.com/go).
+
+settings.json
+
+```
+{
+ "ssid": "******",
+ "password": "***",
+ "atSign": "@alice"
+}
+
+```
+
+3. To get an .atKeys file belonging to an atSign, go to 0:54 of this [video](https://youtu.be/2Uy-sLQdQcA?t=54). The easiest way is to download [atmospherePro](https://atsign.com/apps/atmospherepro/) on your computer (via Microsoft Store on Windows or the Appstore if you're on Mac) and onboarding your atSign via the onboarding widget in the app. There are other ways to generate the encryption .atKeys file for an atSign (such as the [at_onboarding_cli on Dart](), [RegisterCLI on Java](), the [sshnp_register_tool in at_tools](), [OnboardingCLI in Java]()) but generating it through [atmospherePro](https://atsign.com/apps/atmospherepro/) is the easiest if you don't want to deal with any code. If you have an .atKeys file (like '@bob232.atKeys'), then move onto the next step. We are going to put our atKeys on the Pico W.
+
+4. Run the "Start FTP server" command to start the FTP server on your Pico W Go. You should be given an address in the terminal (similar to the image below):
-4. Open [FileZilla](https://filezilla-project.org/) and connect to this address. If it asks for a password, the password should be `pico`. If you've uploaded and files to the Pico before, you should see them once you've connected. Similar to below:
+5. Open [FileZilla](https://filezilla-project.org/) and connect to this address. If it asks for a password, the password should be `pico`. If you've uploaded and files to the Pico before, you should see them once you've connected. Similar to below:
-5. Create a `keys/` directory. This is where you will drag and drop the .atKeys file. Your `/keys/` directory should look like this:
+6. Create a `keys/` directory. This is where you will drag and drop the .atKeys file. Your `/keys/` directory should look like this:
-6. Close the FTP server by pressing "Stop" on the bottom toolbar on VSCode.
+7. Close the FTP server by pressing "Stop" on the bottom toolbar on VSCode.
Stop button:
@@ -113,11 +188,11 @@ Yay our FTP server is closed:
-7. Now we have to put our keys in the Pico W, it's time to run `main2.py`. First upload all dependencies and files by running the command "Upload project". This will upload all the files in your project to the Pico W. You may run into some freezing and errors, but just keep trying by disconnecting/reconnecting and unplugging/replugging the Pico W.
+8. Now we have to put our keys in the Pico W, it's time to run `test_3_pkam_authenticate.py`.
-8. Now open `main2.py` and run the "Run current file" command. You should see something similar to this: If your code has 1. connected to the Internet and 2. found the address of your secondary server, then move onto the next step!
+Output should be similar to:
-
+
If you don't see this, ensure your settings.json looks like this (with an atSign you own):
@@ -133,12 +208,4 @@ and that you have the .atKeys file in the `/keys/` directory.
-9. This is the tricky part. Now we are going to write some atProtocol. Go into `main2.py` and this part of the code:
-
-
-
-10. Depending on what you are doing, you will need to comment A) and edit B) or vice versa. If you are trying to receive data from another atSign's secondary, you will use code under A), and if you are sending data to another atSign's secondary, you will use code under B).
-
-## Libraries
-- [iot-core-micropython](https://github.com/GoogleCloudPlatform/iot-core-micropython)
-- [uasn1](https://github.com/mkomon/uasn1)
+## 6. Sending end-to-end encrypted data
\ No newline at end of file
diff --git a/test_1_wifi.py b/test_1_wifi.py
index 325172c..598f414 100644
--- a/test_1_wifi.py
+++ b/test_1_wifi.py
@@ -1,6 +1,12 @@
def main():
+ """
+ Sample output
+
+ >>> Connecting to Soup (Ctrl+C to stop)...
+ >>> Connected to WiFi Soup: True
+ """
from lib.at_client import io_util
from lib import wifi
diff --git a/test_4_send_data.py b/test_4_send_data.py
new file mode 100644
index 0000000..7be7a94
--- /dev/null
+++ b/test_4_send_data.py
@@ -0,0 +1,76 @@
+
+
+def main():
+ shouldRun = str(input('Run? (y/n): '))
+ if shouldRun == 'n':
+ import sys
+ sys.exit(1)
+
+ from lib.at_client import keys_util
+ from lib.at_client import io_util
+ from lib.at_client import remote_secondary
+ from lib import wifi
+ from lib.third_party import rsa
+ from lib.at_client.at_utils import without_prefix
+ ssid, password, atSign = io_util.read_settings()
+ keys_util.initialize_keys(atSign) # initialize /keys/@{your_atSign}/ containing _pem.json keys extracted from /keys/@fascinatingsnow_key.atKeys, you really only need to run this once per atSign
+
+ atSignWithoutPrefix = without_prefix(atSign)
+ rootUrl = 'root.atsign.org:64'
+
+ print('Connecting to WiFi %s...' % ssid)
+ wlan = wifi.init_wlan(ssid, password)
+
+ remote_secondary = remote_secondary.RemoteSecondary(rootUrl, atSign, wlan)
+ print('Connecting to remote secondary of atSign @%s...' % atSignWithoutPrefix)
+ remote_secondary.connect_to_secondary()
+ print('Connected to secondary of atSign @%s with address %s' %(atSignWithoutPrefix, str(remote_secondary.get_secondary_address())))
+ if remote_secondary.is_connected():
+ print('Sending from:%s' % atSign)
+ response, command = remote_secondary.send_verb('from:%s' %atSignWithoutPrefix)
+ challenge = response.replace('@data:', '')
+ print('Challenge: %s' % challenge)
+ print('Digesting...')
+ pemPkamPrivateKey = keys_util.get_pem_pkam_private_key_from_file(atSign) # parameters
+ rsaPkamPrivateKey = rsa.PrivateKey(pemPkamPrivateKey[0], pemPkamPrivateKey[1], pemPkamPrivateKey[2], pemPkamPrivateKey[3], pemPkamPrivateKey[4])
+ signature = b42_urlsafe_encode(rsa.sign(challenge, rsaPkamPrivateKey, 'SHA-256'))
+ print('Signature: %s' % str(signature))
+ response, command = remote_secondary.send_verb('pkam:' + signature)
+ print(response) # data:success
+
+ del signature, challenge, rsaPkamPrivateKey, pemPkamPrivateKey, ssid, password
+
+ import time
+ time.sleep(1)
+ del time
+
+ # Now we're logged in!
+ # Consider
+ # - @smoothalligator as the app atSign
+ # - @fascinatingsnow as the IoT Pico W atSign
+
+ # A) Receive data from another atSign
+ # theirAtSign = '@smoothalligator'
+ # keyName = 'led'
+ # for i in range(50):
+ # response, command = remote_secondary.send_verb('lookup:%s%s' % (keyName, theirAtSign))
+ # if response != None:
+ # response = response.replace('@data:', '')
+ # print(response) # 0, 1
+
+ # B) Send a message to another atSign
+ # theirAtSign = '@smoothalligator'
+ # keyName = 'message'
+ # value = 'some message'
+ # updateCommand = ('update:%s%s %s' %(keyName, theirAtSign, value))
+ # print('ran command: %s' %updateCommand)
+ # response, command = remote_secondary.send_verb(updateCommand)
+ # print(response)
+
+def b42_urlsafe_encode(payload):
+ from lib.third_party import string
+ from ubinascii import b2a_base64
+ return string.translate(b2a_base64(payload)[:-1].decode('utf-8'),{ ord('+'):'-', ord('/'):'_' })
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file