Skip to content

Commit 015c58f

Browse files
committed
mqtt sub
1 parent f0f140b commit 015c58f

File tree

2 files changed

+185
-0
lines changed

2 files changed

+185
-0
lines changed

contrib/mqtt/mqtt.forth

+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
2+
stack-clear
3+
\ common words for communication with mqtt broker
4+
NETCON load
5+
DECOMP load
6+
7+
\ configuration for communicating with your broker
8+
"192.168.1.172" constant: broker_addr
9+
1883 constant: broker_port
10+
"YourMQTT-ClientId" constant: mqtt-clientid
11+
12+
\ mqtt message types
13+
\ 10 = CONNECT message type
14+
16r10 constant: msgtype_connect
15+
16r20 constant: msgtype_conact
16+
16rE0 constant: msgtype_disconnect
17+
16r30 constant: msgtype_publish
18+
16r82 constant: msgtype_subscribe
19+
16r90 constant: msgtype_subresp
20+
21+
\ socket reference to broker
22+
variable: broker
23+
24+
\ communication packet buffer. expect small packets
25+
255 constant: packet_size
26+
packet_size byte-array: packet
27+
\ paki is an index into packet byte array when building the packet
28+
\ note that the packet size to send is 1+ the paki value
29+
variable: paki
30+
31+
\ store two byte number into an address
32+
: !pack-num ( num addr -- )
33+
2dup
34+
\ store high order byte to address
35+
swap 8 rshift swap c!
36+
\ store low order byte to address+1
37+
1+ c! ;
38+
39+
\ store string at an address
40+
: !str ( s addr -- )
41+
swap dup strlen ( addr s len )
42+
rot swap ( s addr len )
43+
cmove ;
44+
45+
\ store string into len+string struct that mqtt likes (packed string)
46+
: !pack-str ( s addr -- len)
47+
2dup ( s addr s addr)
48+
swap strlen dup >r swap ( s addr len addr)
49+
!pack-num ( s addr)
50+
\ fill rest of buffer with the string
51+
2 + ( s addr )
52+
r> dup >r ( s addr len )
53+
cmove ( )
54+
\ return length of string we just stored plus the length of num
55+
r> 2 +
56+
;
57+
58+
\ establish tcp socket connection to broker
59+
: mqtt-con broker_port broker_addr TCP netcon-connect broker ! ;
60+
: mqtt-close broker @ netcon-dispose ;
61+
\ send packet to broker
62+
: send-pak broker @ rot rot netcon-write-buf ;
63+
: send-packet 0 packet paki @ send-pak ;
64+
\ store single byte character in packet
65+
: !c-packet ( c -- ) paki @ packet c! 1 paki +! ;
66+
\ store packed string in packet
67+
: !str-packet ( s -- ) paki @ packet !pack-str paki +! ;
68+
\ store message length in the packet header ie. packet size - 2
69+
: !packet-len paki @ 2 - 1 packet c! ;
70+
71+
\ stores mqtt CONNECT command into packet
72+
: make-packet-connect
73+
\ initialize the index into the byte-array
74+
0 paki !
75+
msgtype_connect !c-packet
76+
1 paki +!
77+
\ msg len, must be calculated at the end
78+
\ protocol name
79+
"MQTT" !str-packet
80+
\ protocol version
81+
16r04 !c-packet
82+
\ flags
83+
16r02 !c-packet
84+
\ keep-alive
85+
60 paki @ packet !pack-num
86+
2 paki +!
87+
\ clientid
88+
mqtt-clientid !str-packet
89+
!packet-len
90+
;
91+
92+
: make-packet-disconnect ( -- )
93+
0 paki !
94+
msgtype_disconnect !c-packet
95+
1 paki +!
96+
\ 2 - 2 = 0, will store 0
97+
!packet-len ;
98+
99+
: make-packet-publish ( topic msg -- )
100+
0 paki !
101+
msgtype_publish !c-packet
102+
1 paki +!
103+
\ store topic with length
104+
swap !str-packet
105+
dup strlen swap paki @ packet !str paki +!
106+
!packet-len ;
107+
108+
\ compare buffer contents
109+
: =buf ( b1 b2 n -- T|F)
110+
0 do
111+
2dup
112+
i + c@ swap i + c@ <> if
113+
2drop unloop FALSE exit then
114+
loop
115+
2drop TRUE ;
116+
117+
\ read message from broker into packet and store length
118+
: read-broker broker @ packet_size 0 packet netcon-read
119+
paki ! ;
120+
121+
\ compare broker response to expected response
122+
: expect ( buf n -- TRUE | FALSE)
123+
paki @
124+
dup -1 = if \ no bytes read from broker
125+
2drop FALSE exit
126+
then
127+
dup rot <> if \ did not read the expected number of bytes
128+
2drop FALSE exit
129+
then
130+
0 packet swap =buf ;
131+
132+
create: pak-conack 16r20 c, 16r02 c, 16r00 c, 16r00 c,
133+
create: pak-disconnect 16re0 c, 16r00 c,
134+
135+
: expect-conack pak-conack 4 expect ;
136+
137+
: print-results
138+
if
139+
println: "Success" else println: "Failed"
140+
print: "got " paki @ . print: " bytes" cr
141+
then
142+
0 packet 10 dump ;
143+
144+
: mqtt-pub
145+
make-packet-connect mqtt-con send-packet
146+
read-broker expect-conack if
147+
make-packet-publish send-packet
148+
pak-disconnect 2 send-pak
149+
then mqtt-close ;
150+
151+
\ example usage
152+
\ "house/t1" "testmessage" mqtt-pub
153+
\ print-results
154+
/end
155+

contrib/mqtt/readme.md

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# MQTT for PunyForth
2+
3+
* MQTT.forth allows the 8266 to publish messages onto a MQTT message queue using PunyForth
4+
* So far, only pub has been implemented (no sub yet)
5+
6+
# Instructions
7+
Edit the configuration section in the mqtt.forth file. Specifically, enter the ip address of your mqtt broker. Then upload mqtt.forth to your 8266 board. Publish a message using
8+
```
9+
"topic" "message" mqtt_pub
10+
```
11+
If you do not have a broker to test with then install mosquitto.
12+
```
13+
sudo apt-get install mosquitto mosquitto-clients
14+
```
15+
The broker will run automatically but to see broker diagnostics messages use something like
16+
```
17+
sudo /etc/init.d/mosquitto stop
18+
hostname -I
19+
mosquitto -v
20+
```
21+
and subscribe to a topic using
22+
```
23+
mosquitto_sub -h YOUR_IP_ADDRESS -t "YOUR_TOPIC" -d
24+
```
25+
If everything is working then you will see the published messages in your subscriber terminal.
26+
# Contact
27+
28+
29+
Dave Foderick
30+

0 commit comments

Comments
 (0)