As I promised now I publish -- or rather started to publish -- my raw ELM327 command sentences and their descriptions in order to encourage you to try them and confirm whether they working on husky 449 or may be 511 as well. If not, please let's try to jailbreak into them with my simple brute force algorithm founding those possible different secret keys for authentication for your husky ECU and for future use.
I suppose the first two steps to access your ECU via ELM327 are the initial intelligence tests for anybody.
1/ You should connect "somehow" ELM327 OBD connector to your 449 diagnostic interface. It is a quite trivial job, described many places all around the web. I have not checked that but maybe somewhere in this cafehusky forum as well. For the sake of completeness I repeat it briefly: You should connect 3 wires, GND, BATTERY 12V and K-LINE of ELM327 OBD2 connector to the same pins of 449' diagnostic connector. For OBD2 connector pls see
https://en.wikipedia.org/wiki/On-board_diagnostics (GND = pin 4 and 5, BATTERY 12V = pin 16, K-LINE = pin 7. For the 449's (and also for my CCM GP450') diagnostic connector -- from front view of the diagnostic connector (with release button up) --: GND = bottom middle pin, BATTERY 12V = bottom right pin, K-LINE = top left pin. You can make any type of connection. I made a very elegant one, buying the proper male pair of the diagnostic connector, with plastic inserts and those 3 pins. Because it was a bit special connector I think it was the most expensive part of my full HW investment, since ELM327 was much cheaper than this small plastic gadget.
2/ You can use any type of terminal emulator or terminal program of any type of operating system. Old Windows has "Hyperterminal". OSX Mac, Android, iPhone, Raspberry Pi, as UNIX/Linux machines have the standard "Terminal" application on which you can run the "screen" command line program with the relevant USB device and with 38400 baudrate. On my Macbook this command is "screen /dev/ttyUSB0 38400", on my Raspberry Pi this command is "screen /dev/cu.usbserial 38400". The potential tricky part of this job to install proper FTDI USB-Serial driver (
http://www.ftdichip.com/FTDrivers.htm) for these programs, if it has not been already available. This is also very well documented all around the web. My Mac and Raspberry Pi has this driver by default.
ELM237 documentation is available on the following link:
http://elmelectronics.com/DSheets/ELM327DS.pdf
After these necessary steps above as a starting point I suppose you get somehow to the ">" prompt of ELM327. So let's start the game. Commands bolded are the commands you should type in. Repeated non-bold parts of the commands are for description purposes. Texts after # are my descriptions. Request (command) and its response indicated by "req", "resp". Spaces between characters is not necessary. But I will put spaces into the commands for better readability. 0x sign before numbers in my description means that it is a hexadecimal number. BTW all data in commands and answers are hexadecimal
req
ATZ # reset ELM327
resp
OK
req
ATL1 # switch LF (line feed) on - after reset ELM327 responses in the same line in which we typed, it could be disturbing, with this command we switched on the normal mode
# getting the responses in the next line
resp
OK
req
AT WM 82 12 F1 3E 01 # set wakeup or "heart beat" message - during connection it will be sent by ELM327 in a frequency defined later, in order to maintain the
# communication with the ECU
WM # Wake up Message, the following five bytes are the "wake up message" itself, which will be sent by ELM327 in the predefined frequency
82 # first 2 bits (8) means we use physical addressing in the communication, the last 6 bits (2) gives the length of the message, after the address bytes
12 # ECU address (it was my first finding, because it is BMW/Keihin specific for our 449's ECU
F1 # Test program/device address (address of ELM327) # ECU use this address in its answers
# the following 2 bytes are the content of the message
3E # testerPresent function code/ID - it means: "I'm living, please don't disconnect"

01 # I'm waiting for an answer for my request (based on KWP2000 specification 02 would mean: "don't need answer", but it does not work with our ECU
resp
OK
req
AT SW C8 # set wake up frequency to 4000 ms (4 sec) - so ELM327 will send the previously defined "wake up" message in every 4 sec
SW # Set Wake up
C8 # C8 = hexadecimal value (all values in commands are hexadecimal) of frequency
# C8 = 200 in decimal - we can set wake up frequency by 20 msec increment, so 200x20 msec = 4 sec
resp
OK
req
AT SH 81 12 F1
SH # set header
81 # 8 = we will using physical addresses, 1 = length of message value is placed into the first byte of header
12 # ECU address
F1 # test program/device address (address of ELM327) -- from now these addresses will be used constantly in all further communication
# ELM327 will insert these header bytes/addresses automatically at the beginning of our sent messages
resp
OK
req
AT FI # Fast Init - it is the HW initialisation command, making serial line connection between ECU and ELM327
resp
BUS INIT: OK # hardware or serial line or K-LINE connection to our ECU is OK
# if we get BUS INIT: ERROR message something went wrong (e.g. we have forgot to connect ELM327 and ECU or the physical connection is wrong)
OR:
Mostly the problem is that our ECU is "sleeping" or more precisely it had switched off itself. So they cannot respond to this initialisation command. This is typical for our BMW or Husky 449 or CCM 450 (449) motorcycle. You should have been experienced that when you switched off ignition after several seconds you can hear two noises. The first one came from the stepping motor in throttle body/house, then later a relay is switched off. This relay gives power to our ECU. And this relay is controlled by the ECU. So our ECU is able to switch off its own power so it is able to put itself in "sleep mode". When ignition is switched on, this relay is not switched on yet. So our ECU cannot get power yet. Only the starter relay/motor will switch on this relay and as a consequence switch on our ECU. So, how can you switch on the ECU and communicate/diagnose it without starting the engine. You should push the starter button very briefly. Don't start the engine but only push the button shortly. It gives power to the ECU but don't start the engine. But after that you should type the AT FI command quickly since there is a timing (around half minute) when ECU will switch off itself again. Naturally if you started and your engine is running the ECU will work normally and yo don't need to hurry
After "AT FI" command we've finished the initial "AT" commands (pervious commands beginning with AT are all for ELM327). They were for initial setup purposes. From that time our commands (without AT) will be sent to our ECU (of course via ELM327). In the background ELM327 does its job, puts header bytes, addresses and also checksum to my commands but it manages this automatically. We don't need to care about these details. It is convenient compared to other USB-Serial K-Line interface like VAG 409 cable, for which we need to manage, namely type and send that "message frame bytes" like header, addresses, checksum on our own. It is not a big deal from a program, but inconvenient to calculate and type them every time in every command by hand.
After the succcesful "BUS INIIALISATION" between ELM327 and our ECU, the connection is living. The heart beat messages are automatically sent by ELM327 in every 4 seconds -- you can see it when the leds on ELM327 are flashing -- so communication will not be dropped by ECU. We can send commands to ECU via this maintained communication channel:
req
81 # startCommunication function -- start of diagnostic session
resp
C1 5B 8F # "keyword answer"
# 0xC1 means successful answer for 81 request -- ECU signals OK answer in such a way that it adds 0x40 (hexadecimal 40) to the first -- called -- function byte
# (this case this function byte was 0x81, so 0x81+0x40=0xC1 which means OK for 0x81 function)
# negative answer signalled by an initial 7F byte, then the repeated function byte, then error description byte about the nature of the error (see examples below)
5B 8F # keyword - it is the expectation/specification from ECU what communication parameters it wants to use -- you don't need to care about it
# for professionals: 5B 8F means: 1/ both format byte and additional length byte is possible, 2/ header with target and source addresses, 3/ extended timing
After that command we are in the default access mode, we can ask some basic information from ECU. But let's make authentication and step into the secure access level
req
27 03 # authentication seed request
# 0x27 = authentication function
03 # parameter of authentication function -- 0x03="seed request for access level 2"
resp
67 03 CC 09 # positive response for 0x27 authentication (0x27+0x40=0x67)
03 # OK response always repeats the parameter of the request, in this case it was 0x03
CC 09 # it is the two byte SEED, generated randomly by the ECU, and given us as a response for the previous SEED request
# since we always get random numbers for every request, it is nearly impossible that you get the same bytes which are in this example

# this is the number -- what you really got -- which should be substituted into the next authentication calculation
Here comes the "magic" calculation of the answer (password) based on the secret key for access level 2 and using the authentication algorithm/transformation. If we are able to give a correct answer, ECU will let us enter into its secure level. The secret key -- I hope it is not only for my CCM's, but also for your husky 449's ECU -- is the mentioned 0x1EC3 for secure level 2. The transformation is
(SEED * 0x1EC3)%0x10000. You need a hexadecimal calculator to calculate directly or convert all numbers into decimal, make calculation, then convert the result back to hexadecimal.
Hexadecimal calculation: 0xCC09*0x1EC3=0x1884
78DB, then 0x1884
78DB%0x10000=0x78DB, the lower 16 bit part of the result.
If you have no other possibilities for decimal calculation open an Excel table and use HEX2DEC and DEC2HEX functions, and also Excel % (modulo operator).
In our case/example we've calculated our magic response =
0x78DB which should be sent back as answer/password to the ECU.
req
27 04 78 DB # authentication response
# 0x27 = authentication function
04 # parameter of authentication function -- 0x04="response for access level 2"
78 DB # our calculated answer for ECU, it is our dynamic password for authenticate ourself for accessing secure level 2
resp
67 04 # positive authentication response
# positive response for 0x27 request (0x27+0x40=0x67)
04 # OK response always repeats the parameter of the requested function, in this case it was 0x04
In case of error when ECU don't accept our authentication we can got the following error messages:
resp
7F 27 10 # 7F = error in a previous command
27 # it was the 0x27 authentication function where this error occured
10 # 0x10 means GENERAL_ERROR, which means that ECU cannot accept our responses/password
or
resp
7F 27 37 # 7F = error in a previous command
27 # it was the 0x27 authentication function where this error occured
37 # 0x37 means ERROR_TIME_DELAY_NOT EXPIRED, which means that we've tried to send/repeat answer/password in less than 10 sec
So Guys, if somebody got that
67 04 answer, it means that his/her ECU accepted the password. in this case we have win

. Your husky ECU use the same -- non BMW -- secret key for authentication as my CCM GP450. After this you/we can access all diagnostic and other features of your/our ECU. If you get
7F 27 10 error message, ECU refused your password. There are 3 possibilities: 1 / secret key was OK, but your calculation was false, let's try again, 2/ some time ECU is busy to deal with your request it is why it refuses, let's try again, 3/ secret key is different from CCM changed secret key for the same type of ECU. In this case please try to substitute BMW original secret key (
0x1923 instead of 0x1EC3) into the authentication formula. I don't believe but it can be possible that BMW/Keihin did not change the original secret keys for husky's ECU. Please don't give up for the first failure try again and ensure that everything was OK, the password calculation was OK, and you tried it several times.
I assume you were successful. So -- as appetising -- here I tried to document two types of request examples. 1/ with the 0x22 function (ReadDataByCommonIdentifier) we can query many parameters and data. After the 0x22
read function you should specify the identifier of requested data. 2/ with the 0x31 function (StartRoutineByLocalIdentifier) you can make ECU to run its own internal program routines. After the 0x31
run function you should specify the identifier of ECU's internal program routines. BTW these identifiers are the same as in KTM Keihin ECUs.
Let's see some "READ" functions:
req
22 0007 # read BatteryVoltage
# 0x22 = ReadDataByCommonIdentifier function
0007 # identifier of battery voltage -- this is the place where ECU stores the value of current Battery Voltage
resp
62 00 07 00 89 # OK answer for read BatteryVoltage
# OK answer 0x22+0x40=0x62
00 07 # identifier of battery voltage
00 89 # value of current battery voltage
# 0x89 = 137 in decimal
# ECU measure battery voltage in 0.1 V increments, so 137 means that our battery voltage is 13.7 V
req
22 0009 # read engine coolant temperature
# 0x22 = ReadDataByCommonIdentifier function
0009 # identifier of coolant temperature
resp
62 00 09 00 43 # OK answer for read engine coolant temperature
# OK answer 0x22+0x40=0x62
00 09 # identifier of engine coolant temperature
00 43 # value of current engine coolant temperature
# 0x43 = 67 in decimal
# ECU measure engine coolant temperature from -40 degrees, so 67 means that our coolant temperature is 27 degrees
req
22 0001 # read throttle position current angle
# 0x22 = ReadDataByCommonIdentifier function
0001 # identifier of throttle position current angle
resp
62 00 01 00 05 # OK answer for read throttle position current angle
# OK answer 0x22+0x40=0x62
00 01 # identifier of throttle position current angle
00 05 # value of throttle position current angle
# 0x05 = 5 in decimal
# ECU measures the position of throttle from 0 deg to 80 deg on its scale from 0x00 (0) to 0xFF (255).
# So you can calculate the degrees: got value * 80 / 255 -> in my case 5 * 80 / 255 = 1.56 deg
# or you can calculate in %: got value * 100 / 255 -> in my case 5 * 100 / 255 = 1.96%
You can play with this value. Rotate grip and push Enter key on your computer many times quickly. If ELM327 got an Enter in an empty command it repeats the previous command then we can see the response. So hitting the enter key quickly during twisting my throttle grip gives the following result:
62 00 01 00 05 -> 1 degree = 1% (rounded)
62 00 01 00 3B -> 18 degrees = 23%
62 00 01 00 6D -> 34 degrees = 42%
62 00 01 00 AC -> 53 degrees = 67%
62 00 01 00 FF -> 80 degrees = 100% = full gas
62 00 01 00 05 -> 1 degree = 1%
I will publicate and explain all other possibly queries later
Let's try some "RUN" functions:
req
31 A501 # start injection valve test - injector repeatedly activated, automatically stops after 10 seconds
# 0x31 = StartRoutineByLocalIdentifier
A501 # identifier of start injection valve test
resp
71 A5 01 # OK answer for injection valve test
# OK answer 0x31+0x40=0x71
A5 01 # identifier of start injection valve test
# you can hear the repeated injector activities for 10 seconds
req
31 A700 # start fuel pump relay test - fuel pump really activated for 10 seconds
# 0x31 = StartRoutineByLocalIdentifier
A700 # identifier of start fuel pump relay test
resp
71 A7 00 # OK answer for start fuel pump relay test
# OK answer 0x31+0x40=0x71
A7 00 # identifier of start fuel pump relay test
# you can hear the repeated fuel pump activities for 10 seconds (in shorter intervals in order not to overload the pump)
I will publicate and explain all other possibly actuator tests later.
It was a long post. Sorry about it. I know that it was bit technical, but I hope you enjoyed this

As I mentioned earlier on top of this inconvenient command usage of ELM327 any middle skilled programmer can build any type of beautiful applications with graphical gauges, instruments, menus, etc. Let's consider it as a test which should have been passed by somebody in your husky community. Since I have no husky or its ECU to try these commands. As we discussed earlier if you have an authentication success, and have jailbroken into your ECU we will find some more user friendly solution for using these feature of our ECU.
If you test it and not working, we need an entrepreneur to whom I can send my stupid brute force test algorithm. It is safe to run. Only it takes some time (may be some days) to find your ECU's secret key. So during this time somebody is missing its bike. Although if he/she build -- e.g. those tiny credit card size -- computers in his/her bike, my program are able to scan ECU during motorcycling as well
gobftald