iPhone 7 – where’s the innovation?

The iPhone 7 is probably going to be noticed more for what Apple has removed, rather than the faster processor and improved dual lens zoom camera, since this is the first iPhone without a headphone jack.

Apple is notable for removing features on their new products though – laptops and desktops (iMac) with no floppy drive, and then later, no optical drive (MacBook Air).

PCMagazine added this perfect statement:

People who want iPhones don’t want them because of the spec sheets. They want them because of iOS, third-party iOS apps, Apple’s service and support network, and the community effects of Apple-only systems like iMessage.

Apple has succeeded so well at creating desirable products, that if they announced an iPhone 8 today with no new or additional features over the just announced iPhone 7, people would still buy it, just because it’s “one better”.

Winlink amateur radio email via paclink-unix on the Raspberry Pi

This is my second attempt to get a Winlink client (see here for a high level overview of Winlink) working on the Raspberry Pi. I first tried Pat /wl2k-go but it crashed (I created a ticket on github to followup), so for my second attempt I took a look at paclink-unix.

This site has a very detailed step by step install and config steps – follow exactly and pay attention to any errors 🙂 : http://bazaudi.com/plu/doku.php?id=plu:install_plu

A few additional notes:

  • wl2kax25 did not compile for me with the ax25 version that I previously had installed, possibly from apt-get from the default repos. Once I noticed this was missing I went back to the steps in the doc above and downloaded the ax25 packages from source, compiled, installed, rebuilt paclink and now I had the wl2kax25 app
  • Editing the /usr/local/etc/wl2k.conf file: the email= value is your local user email address on your local device, in this case on the Pi (e.g. for me, pi@localhost). This is used when wl2ktelnet/wl2kax25 retrieves incoming messages and it sends them to this user. If you see the wl2k app downloading messages but they’re not showing up in your inbox, check this.
  • Checking /var/log/mail.log is very useful to see what’s happening to your outbound and inbound messages!

The usage sequence is:

  • send outbound message with mail client, e.g. alpine
  • run wl2ktelnet to send over an internet connection if you have one
  • or, run wl2kax25 to send over your configured ax25 stack

The setup I got working is:

  • Raspberry Pi, with alpine (regular email client), direwolf (packet soundcard modem) and ax25 (to link paclink to direwolf)
  • Rigblaster Advantage USB soundcard, connected to an Icom 880

To send over vhf to my nearest Winlink gateway, I used:

  • wl2kax25 -a 1 -c KG6SJT-10 via KBERR

Where

-a 1 is port 1 defined in my /etc/ax25/axports

-c is the call of the Winlink gateway I’m connecting to, and I’m connecting via a packet digipeater, KBERR.

Raspberry Pi Winlink client over 2m VHF using Pat/wlk2-go + Direwolf + ax25 (not working yet)

Some rough notes on getting this combination working. This is my first attempt in getting the Pat / wlk2-go Winlink client working on a Raspberry Pi. I’m using:

  • Direwolf as a packet soundcard modem
  • ax25 as the connection between the Pat Winlink client and Direwolf
  • a Rigblaster Advantage, as a USB soundcard interface between the Raspberry Pi and a 2m transceiver (an Icom ID-880H)

I already have Direwolf and ax25 networking configured from using my Pi as a Packet radio client (search for my previous blog posts on Direwolf and you’ll find my notes for installing and configuring). Following the instructions in the Pat wiki here, I added a new ax25 interface as a new line to the end of my /etc/ax25/axports files:

wl2k KK6DCT 0 255 7 2m winlink

The wl2k alias for the new port I think is the default that Pat looks for to connect.

Note: I already have Direwolf configured with a 1200 port for VHF packet so I reused this as my first test, but if you configure a 300 port for HF and then connect the Rigblaster to an HF radio, I think the setup will be much the same (I haven’t tried this yet, but this will be my next test).

Next I installed golang on the pi with:

sudo apt-get install golang

and then installed Pat with:

go get github.com/la5nta/pat

go get failed initially with $GOPATH not set. So I created go-workspace in my home dir, and then did

export GOPATH="$HOME/goworkspace"

and added this export to my .bashrc so it will be set next time I log on too.

Now the go get started downloading to goworkspace, but it seemed to hang before it completed. Alternatively, you can download a prebuild .deb file from the Pat github releases page and install with (I used this approach instead):

sudo dpkg -i pat_0.1.5_linux_armhf.deb

pat configure – opens an editor for the config file. I added my callsign in mycall, my winlink password.

To add an alias in the configuration for a connection via ax25, I added a connection to KG6SJT-10, which is my closes Winlink gateway on 2m:

“connect_aliases”: {
“KG6SJT-10”: “ax25:///KG6SJT-10”,
“telnet”: “telnet://{mycall}:CMSTelnet@server.winlink.org:8772/wl2k”
}

pat http – starts the web interface

From the web gui at localhost:8080 you can select the Connect menu item, select the alias added in the config above, but this blew up Pat when I tried it. Time to log a ticket:

2016/09/07 00:20:53 Connecting to KG6SJT-10 (ax25)…
fatal error: unexpected signal during runtime execution
[signal 0xb code=0x1 addr=0x0 pc=0x76f3d774]

runtime stack:
runtime.throw(0x5d0948, 0x2a)
/opt/go/src/runtime/panic.go:547 +0x78
runtime.sigpanic()
/opt/go/src/runtime/sigpanic_unix.go:12 +0x44

goroutine 53 [syscall, locked to thread]:
runtime.cgocall(0x457ff0, 0x10c6b7e4, 0x0)
/opt/go/src/runtime/cgocall.go:123 +0x11c fp=0x10c6b7c4 sp=0x10c6b7ac
github.com/la5nta/pat/vendor/github.com/la5nta/wl2k-go/transport/ax25._Cfunc_ax25_aton_entry(0x0, 0x10ed00b0, 0x0)
??:0 +0x38 fp=0x10c6b7e0 sp=0x10c6b7c4
github.com/la5nta/pat/vendor/github.com/la5nta/wl2k-go/transport/ax25.(*ax25Addr).setPort(0x10ed00a0, 0x10b5a250, 0x4, 0x0, 0x0)
/home/martinhpedersen/go/src/github.com/la5nta/pat/vendor/github.com/la5nta/wl2k-go/transport/ax25/ax25_linux.go:361 +0x64 fp=0x10c6b7f0 sp=0x10c6b7e0
github.com/la5nta/pat/vendor/github.com/la5nta/wl2k-go/transport/ax25.DialAX25Timeout(0x10b5a250, 0x4, 0x10b5a158, 0x6, 0x10d107cd, 0x9, 0x7a358200, 0xa, 0xcb8e4, 0x0, …)
/home/martinhpedersen/go/src/github.com/la5nta/pat/vendor/github.com/la5nta/wl2k-go/transport/ax25/ax25_linux.go:136 +0x16c fp=0x10c6b984 sp=0x10c6b7f0
github.com/la5nta/pat/vendor/github.com/la5nta/wl2k-go/transport/ax25.Dialer.DialURL(0x7a358200, 0xa, 0x10d108d0, 0x0, 0x0, 0x0, 0x0)
/home/martinhpedersen/go/src/github.com/la5nta/pat/vendor/github.com/la5nta/wl2k-go/transport/ax25/ax25.go:114 +0x278 fp=0x10c6ba8c sp=0x10c6b984
github.com/la5nta/pat/vendor/github.com/la5nta/wl2k-go/transport/ax25.(*Dialer).DialURL(0x7c39f8, 0x10d108d0, 0x0, 0x0, 0x0, 0x0)
<autogenerated>:1 +0xb8 fp=0x10c6baac sp=0x10c6ba8c
github.com/la5nta/pat/vendor/github.com/la5nta/wl2k-go/transport.DialURL(0x10d108d0, 0x0, 0x0, 0x0, 0x0)
/home/martinhpedersen/go/src/github.com/la5nta/pat/vendor/github.com/la5nta/wl2k-go/transport/dial.go:29 +0xbc fp=0x10c6bad4 sp=0x10c6baac
main.Connect(0x10d107c5, 0x11, 0x0)
/home/martinhpedersen/go/src/github.com/la5nta/pat/connect.go:108 +0x7b4 fp=0x10c6bc5c sp=0x10c6bad4
main.ConnectHandler(0x76457918, 0x10c1b200, 0x10bf8230)
/home/martinhpedersen/go/src/github.com/la5nta/pat/http.go:357 +0x68 fp=0x10c6bca8 sp=0x10c6bc5c
net/http.HandlerFunc.ServeHTTP(0x6208b4, 0x76457918, 0x10c1b200, 0x10bf8230)
/opt/go/src/net/http/server.go:1618 +0x34 fp=0x10c6bcb8 sp=0x10c6bca8
github.com/la5nta/pat/vendor/github.com/gorilla/mux.(*Router).ServeHTTP(0x10a114a0, 0x76457918, 0x10c1b200, 0x10bf8230)
/home/martinhpedersen/go/src/github.com/la5nta/pat/vendor/github.com/gorilla/mux/mux.go:107 +0x250 fp=0x10c6bd44 sp=0x10c6bcb8
net/http.(*ServeMux).ServeHTTP(0x10a0ea80, 0x76457918, 0x10c1b200, 0x10bf8230)
/opt/go/src/net/http/server.go:1910 +0x164 fp=0x10c6bd70 sp=0x10c6bd44
net/http.serverHandler.ServeHTTP(0x10a75680, 0x76457918, 0x10c1b200, 0x10bf8230)
/opt/go/src/net/http/server.go:2081 +0x190 fp=0x10c6bda0 sp=0x10c6bd70
net/http.(*conn).serve(0x10b841c0)
/opt/go/src/net/http/server.go:1472 +0xee4 fp=0x10c6bfcc sp=0x10c6bda0
runtime.goexit()
/opt/go/src/runtime/asm_arm.s:990 +0x4 fp=0x10c6bfcc sp=0x10c6bfcc
created by net/http.(*Server).Serve
/opt/go/src/net/http/server.go:2137 +0x3bc

Replacing a MacBook Pro optical drive with a SSD: stripped screws a-plenty

Older model MacBook Pros typically came with a rotational hard disk and an optical  disk. Some models had a 6Gbps SATA controller for the HDD and a 3Gbps controller on the optical drive bay. It’s worth checking in the System Information tool if the controller for the optical bay is not slower than the HDD bay. If it is then you might want to consider swapping out your HDD for the SDD. If both bays are 6Gbps on both sides, then it’s ok to put an SDD in the optical bay and not limit it’s throughput.

My mid-2012 MBP has 6Gbps on both bays:

HDD:

Optical bay:

 

I used an OWC drive doubler bracket to put my SSD into my optical bay. Here’s the patient open and ready to receive it’s new drive. Existing HDD at the top right, optical drive bay bottom right. The bag of tools comes with the OWC bracket:

 The OWC bracket is more pricey at $29 on Amazon, compared to the cheaper alternatives at < $10, but the difference in price seems to be you get everything you need in be box, including tools, replacement screws, and a manual. The manual is incredibly detailed and covers step by step with photos for each MBP model that the bracket fits. Find you model, follow the steps, done.

The replacement probably should take you less than an hour, but I ran into one of the soft black screws that wouldn’t budge and it stripped pretty much instantly. I tried the elastic band trick, I tried supergluing a screwdriver to the screw.., no good.

Drilling out a stripped screw is probably the last resort, unless you can reach it with a dremel and cut a slot into the top. This one was recessed, so did some reading around and a ‘Grabit’ seemed to be the way to go.

The screw in question for me was the larger one in step #8 in iFixit’s instructions here. The instructions even say:

Take care, as these screws are unusually easy to strip

Yep. I think that should actually say:

These screws are guaranteed to strip. Make sure you have tools at hand to remove them when stripped.

The Grabit Micro #1 and #2 did the job for me. The #1 seemed the one to use. Using the drill end, it took a while to drill a whole into the top of my stripped screw. Flipping the drill bit around to the extraction end, it didn’t catch like it was supposed to. At that point I thought my only option was to drill the screw out, so I swapped the next up size and started slowly drilling, but the drill bit end actually caught inside the hole. Since the drill and extractor ends both turn anticlockwise, it immediately started to remove the screw. Phew!

So hows the SSD? It’s awesome. Whereas before El Capitan seemed to take more than a minute (I hadn’t timed it, but roughly) to cold boot on my i7 2012 MacBook Pro, from a clean install on this SanDisk SSD, it boots to logon in around 6 to 7 seconds. Pretty damn incredible. It boots from cold it the same time it would take to come out of sleep from my HDD. And using OS X is incredibly damn fast and fluid. My 2012 MBP has a couple more years of life to go 🙂