Skip to content

Commit b06765a

Browse files
authored
Merge pull request #196 from husigeza/Coap_publish
Adding CoAp documentation
2 parents 5ae5cf5 + 8edcbd2 commit b06765a

File tree

2 files changed

+224
-1
lines changed

2 files changed

+224
-1
lines changed

config.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,12 +716,19 @@ theme = "doc-theme"
716716
parent = "firmwareapi@pycom@network"
717717
weight = 20
718718

719+
[[menu.main]]
720+
name = "CoAP"
721+
url = "/firmwareapi/pycom/network/coap/"
722+
identifier = "firmwareapi@pycom@network@coap"
723+
parent = "firmwareapi@pycom@network"
724+
weight = 30
725+
719726
[[menu.main]]
720727
name = "Bluetooth"
721728
url = "/firmwareapi/pycom/network/bluetooth/"
722729
identifier = "firmwareapi@pycom@network@bluetooth"
723730
parent = "firmwareapi@pycom@network"
724-
weight = 30
731+
weight = 40
725732

726733
[[menu.main]]
727734
name = "GATT"
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
---
2+
title: "CoAP"
3+
aliases:
4+
- firmwareapi/pycom/network/coap.html
5+
- firmwareapi/pycom/network/coap.md
6+
- chapter/firmwareapi/pycom/network/coap
7+
---
8+
This module implements a CoAp Server and Client, operating as both at the same time.
9+
10+
## Usage Example
11+
12+
```python
13+
14+
from network import WLAN
15+
from network import Coap
16+
import uselect
17+
import _thread
18+
19+
# The callback that handles the responses generated from the requests sent to a CoAp Server
20+
def response_callback(code, id_param, type_param, token, payload):
21+
print("Code: {}".format(code))
22+
# The ID can be used to pair the requests with the responses
23+
print("ID: {}".format(id_param))
24+
print("Type: {}".format(type_param))
25+
print("Token: {}".format(token))
26+
print("Payload: {}".format(payload))
27+
28+
# Thread handling the sockets
29+
def socket_thread(p, coap_socket):
30+
while True:
31+
# Wait for any socket to become available
32+
sockets = p.poll()
33+
for s in sockets:
34+
sock = s[0]
35+
event = s[1]
36+
if(event & uselect.POLLIN):
37+
# Check if the socket belongs to the CoAp module
38+
if(sock == coap_socket):
39+
# Call Coap.read() which parses the incoming CoAp message
40+
Coap.read()
41+
42+
43+
# Connect to the network
44+
wlan = WLAN(mode=WLAN.STA)
45+
wlan.connect('your-ssid', auth=(WLAN.WPA2, 'your-key'))
46+
47+
# Initialise the CoAp module
48+
Coap.init(str(wlan.ifconfig()[0]), service_discovery=True)
49+
50+
# Add a resource with a default value and a plain text content format
51+
r = Coap.add_resource("resource1", media_type=Coap.MEDIATYPE_TEXT_PLAIN, value="default_value")
52+
# Add an attribute to the resource
53+
r.add_attribute("title", "resource1")
54+
# Add an attribute to the resource
55+
r.add_attribute("ct", str(Coap.MEDIATYPE_TEXT_PLAIN))
56+
# Configure the possible operations on the resource
57+
r.callback(Coap.REQUEST_GET | Coap.REQUEST_POST | Coap.REQUEST_PUT, True)
58+
59+
# Add a resource without default value, XML content format and E-Tag enabled
60+
r = Coap.add_resource("resource2", media_type=Coap.MEDIATYPE_APP_XML, etag=True)
61+
# Configure the possible operations on the resource
62+
r.callback(Coap.REQUEST_GET | Coap.REQUEST_POST | Coap.REQUEST_PUT | Coap.REQUEST_DELETE, True)
63+
64+
# Register the response handler for the requests that the module initiates as a CoAp Client
65+
Coap.register_response_handler(response_callback)
66+
67+
# Get the UDP socket created for the CoAp module
68+
coap_server_socket = Coap.socket()
69+
70+
# Create a new poll object
71+
p = uselect.poll()
72+
# Register the CoAp module's socket to the poll
73+
p.register(coap_server_socket, uselect.POLLIN | uselect.POLLHUP | uselect.POLLERR)
74+
75+
# Start a new thread which will handle the sockets of "p" poll
76+
_thread.start_new_thread(socket_thread, (p, coap_server_socket))
77+
78+
# Send a request to a CoAp server
79+
id = Coap.send_request("192.168.0.234", Coap.REQUEST_GET, uri_port=5683, uri_path=".well-known/core", payload="payload", token="token1", include_options=True)
80+
print(id)
81+
82+
```
83+
84+
## Initialization
85+
86+
#### Coap.init(address, *, port=5683, service_discovery=False)
87+
88+
Initialize the CoAp module.
89+
90+
The arguments are:
91+
92+
* `address` is the address where the CoAp module handles communication.
93+
* `port` is the port where the CoAp module listens. If not set, the default CoAp UDP port is 5683.
94+
* `service_discovery` is a Boolean argument that enables/disables service discovery. If enabled, the CoAp module will listen on the CoAp multicast address: 224.0.1.187. This is disabled by default.
95+
96+
## Methods:
97+
98+
#### Coap.socket()
99+
100+
Returns with the socket assigned to the given address and port during Coap.init() (= assigned to the CoAp module).
101+
102+
#### Coap.add_resource(uri, *, media_type=-1, max_age=-1, value=0, etag=False)
103+
104+
Creates a resource object and adds it to the CoAp module to operate as a server.
105+
106+
* `uri` is the full path of the resource.
107+
* `media_type` is the media type (CoAp option: Content-Format) of the resource. If not given, no defined media type is associated with the resource.
108+
* `max_age` is the maximum time in seconds that the value of the resource is considered fresh (CoAp option: Max-Age). If not given, no fresh time is associated with the resource.
109+
* `value` is the default value of the resource. If not given, it is initialised to decimal 0.
110+
* `etag` is a Boolean argument that enables/disables entity tag calculation (CoAp option: ETag). By default it is turned off.
111+
112+
113+
{{% hint style="info" %}}
114+
Media-type argument is one of the standard defined values that is available via CoAp module's constants.
115+
{{% /hint %}}
116+
117+
{{% hint style="info" %}}
118+
Entity tag calculation is a simple counter increment between value 1-65535 with overflow, it doesn't include the value 0. It is incremented each time and the value of the resource is changed.
119+
{{% /hint %}}
120+
121+
122+
#### Coap.remove_resource(uri)
123+
124+
Removes the resource defined by the `uri` argument.
125+
126+
* `uri` is the full path of the resource to be removed.
127+
128+
#### Coap.get_resource(uri)
129+
130+
Returns with the resource defined by `uri` argument.
131+
132+
* `uri` is the full path of the resource to be returned.
133+
134+
#### Coap.read()
135+
136+
Must be called when a packet is received on the socket assigned to the CoAp module. This function passes on the incoming request, whilst also composing and sending out the response if needed.
137+
138+
#### Coap.register_response_handler(callback)
139+
140+
Registers a callback function which will be called when a remote CoAp Server responses to the local CoAp client's request.
141+
142+
* `callback` is the callback to be registered. It must have the following arguments:
143+
* `code` is the response code from the received message
144+
* `id_param` is the transaction ID of the received message. This can be used to match together requests and the response for it.
145+
* `type_param` is the type flag from the received message
146+
* `token` is the token field from the received message
147+
* `payload` is the payload of the received message
148+
149+
#### Coap.send_request(uri_host, method, *, uri_port=5683, uri_path, content_format, payload, token, include_options=true)
150+
151+
Creates and sends a request to a CoAp server.
152+
153+
* `uri_host` is the IP address of the server, included in the message as an "URI-HOST" option
154+
* `method` is the method to be sent to the server, can be: `Coap.REQUEST_GET`, `Coap.REQUEST_PUT`, `Coap.REQUEST_POST`, `Coap.REQUEST_DELETE`
155+
* `uri_port` is the port of the server, included in the message as an "URI-PORT" option. By default it is 5683
156+
* `uri_path` is the full path of the resource in the server, included in the message as an "URI-PATH" option. If nothing is given the request will not have URI-PATH option.
157+
* `content_format` is the Content-Format option of the request, can be: `Coap.MEDIATYPE_TEXT_PLAIN`, `Coap.MEDIATYPE_APP_LINK_FORMAT`, `Coap.MEDIATYPE_APP_XML`, `Coap.MEDIATYPE_APP_OCTET_STREAM`, `Coap.MEDIATYPE_APP_RDF_XML`, `Coap.MEDIATYPE_APP_EXI`, `Coap.MEDIATYPE_APP_JSON`, `Coap.MEDIATYPE_APP_CBOR`. If nothing is given the request will not have Content-Format option.
158+
* `payload` is the payload of the request. If nothing is given the request will not have payload.
159+
* `token` is the token field of the request. If nothing is given the request will not have token field.
160+
* `include_options` decides whether put any options (including the ones above) into the message or not. It can be used to send special requests to servers accepting CoAp formed requests without options, e.g. to a Dish Telemetry server. By default, the options are included.
161+
162+
## Class resource
163+
164+
The resource class represents a resource in the scope of the CoAp module when acting as a server. A new resource can only be created with the `Coap.add_resource` function.
165+
166+
#### Class methods
167+
168+
The following methods are defined in the scope of the `resource` class.
169+
170+
#### resource.add_attribute(name, value)
171+
172+
Adds a new attribute to the resource. Attributes are used to explain the resource during service discovery.
173+
174+
* `name` is the name of the resource.
175+
* `value` is the value of the resource.
176+
177+
{{% hint style="info" %}}
178+
During service discovery, GET request to ".well-know/core", the attributes are returned with the relevant values.
179+
E.g. using the "libcoap's" command line coap-client to fetch the resource from our server:
180+
181+
coap-client -m get coap://<Coap-Server's address>/.well-known/core
182+
183+
< /resource2>,< /resource1>;ct=0;title=resource1
184+
185+
{{% /hint %}}
186+
187+
#### resource.value(value)
188+
189+
Updates or fetches the value of the resource.
190+
191+
* `value` is the new value to update the current value with.
192+
If the method is called without a parameter, the current value is returned.
193+
194+
#### resource.callback(operation, enable)
195+
To enable or disable a specific operation (GET, PUT, POST, DELETE) on the resource.
196+
197+
* `operation` is the operation to enable/disable, can be ORED of the followings: `Coap.REQUEST_GET`, `Coap.REQUEST_PUT`, `Coap.REQUEST_POST`, `Coap.REQUEST_DELETE`
198+
* `enable` is Boolean parameter that enables/disables the operations specified by `operation`
199+
200+
201+
{{% hint style="info" %}}
202+
During a GET request, only the first occurrence of an ETAG or Accept option is passed on and interpreted; others of the same type are dropped (if any).
203+
{{% /hint %}}
204+
205+
{{% hint style="info" %}}
206+
During a PUT request, only the first occurrence of an If-Match option is passed on and interpreted; others of the same type are dropped (if any).
207+
{{% /hint %}}
208+
209+
{{% hint style="danger" %}}
210+
Due to limitations of the underlying ESP-IDF/libcoap library, new resources cannot be added via PUT or POST requests.
211+
{{% /hint %}}
212+
213+
## Constants
214+
215+
* Define the media type: `Coap.MEDIATYPE_TEXT_PLAIN`, `Coap.MEDIATYPE_APP_LINK_FORMAT`, `Coap.MEDIATYPE_APP_XML`, `Coap.MEDIATYPE_APP_OCTET_STREAM`, `Coap.MEDIATYPE_APP_RDF_XML`, `Coap.MEDIATYPE_APP_EXI`, `Coap.MEDIATYPE_APP_JSON`, `Coap.MEDIATYPE_APP_CBOR`
216+
* Define the operation: `Coap.REQUEST_GET`, `Coap.REQUEST_PUT`, `Coap.REQUEST_POST`, `Coap.REQUEST_DELETE`

0 commit comments

Comments
 (0)