1#!/bin/bash
2
3function start_tcpdump {
4  testfunc=$1
5  logfile=$LOGDIR/"$testfunc"_$(date +%s).dump
6  tcpdumpcmd="$tcpdump -i $INTERFACE host $SERVERADDRESS and (udp port $SERVERPORT or icmp) -s0 -n -w $logfile"
7  if [ $verbose ]; then
8    echo "$tcpdumpcmd"
9    $tcpdumpcmd&
10  else
11    $tcpdumpcmd 2>/dev/null&
12  fi
13  tcpdumppid=$!
14  # wait until tcpdump is ready to write
15  for t in {0..20} ; do
16    if [ ! -e $logfile ] ; then
17      sleep 0.1
18    else
19      sleep 1
20      if [ $verbose ]; then
21        echo "tcpdump started"
22      fi
23      break
24    fi
25  done
26}
27
28function kill_tcpdump {
29  kill $tcpdumppid 2>/dev/null || ERROR=1
30  if [ $ERROR ]; then
31    echo "tcpdump failed."
32    exit 1
33  fi
34}
35
36function start_coap_test {
37  if [ -z $1 ]; then
38    echo "missing argument for start_coap_test"
39    exit 1
40  fi
41  start_tcpdump $1
42  if [ $verbose ]; then
43      echo "client command: $COAP_CLIENT $clientopts $testaddress"
44  fi
45  echo -e "\nOutput of client:"
46  # for OBS
47  if [[ ! -z $2 ]]; then
48    testfifo=/tmp/tmpfifo$(date +%s)
49    mkfifo $testfifo
50    $COAP_CLIENT $clientopts "$testaddress" &> $testfifo &
51    clientpid=$!
52    ($timeoutcmd $clienttimeout cat $testfifo | if read -n 1 char; then echo "output: $char" ; fi) 2>/dev/null
53    # when client has written an output to fifo, kill client
54    kill $clientpid
55    rm $testfifo
56    if [[ $2 == "wait" ]] ; then
57      echo "Client killed. Waiting.."
58      sleep $longtimeout
59    fi
60  else
61    $COAP_CLIENT $clientopts "$testaddress"
62  fi
63  kill_tcpdump
64}
65
66
67##
68# Perform GET (CON mode) on resource /test
69#
70# pre: resource /test exists and can handle GET with arbitrary payload
71#
72# client sends GET request with Type=0(CON) and Code=1(GET)
73#
74# check if sent request contains Type value indicating 0 and Code
75# value indicating 1
76#
77# check if server sends response containing Code = 69(2.05 Content),
78# the same Message ID as that of previous request, content type option
79#
80# verify that server displays received information
81#
82function TD_COAP_CORE_01 {
83  clientopts="$callopts -m get"
84  testaddress=coap://$SERVERTUP/test
85  echo "perform GET (CON mode) on resource $testaddress"
86  start_coap_test $1
87}
88
89##
90# Perform POST transaction (CON mode) on resource /test: create
91# resource /test
92#
93# pre: resource /test doesn't exist but can be created on /test
94#
95# client sends POST with Type=0(CON), Code=2(POST), arbitrary payload,
96# Content type option
97#
98# check: client sends request containing Type value indicating 0 and
99# Code value indicating 2
100#
101# verify: Server displays received information
102#
103# check: server sends response containing Code=69(2.01 Created), same
104# message ID as that of the previous request, Content type option
105#
106# verify: client displays received information
107#
108function TD_COAP_CORE_02 {
109  # -t 0: content type text/plain
110  clientopts="$callopts -m post -t 0 -e sometext"
111  testaddress=coap://$SERVERTUP/test
112  echo "perform POST (CON) on resource $testaddress"
113  start_coap_test $1
114}
115
116##
117# Perform PUT transaction (CON mode) on resource /test
118#
119# pre: resource /test exists which can handle PUT
120#
121# Client sends a PUT request with Type=0(CON), Code=3(PUT), arbitrary
122# payload, content type option
123#
124# check: sent request contains Type value indicating 0 and Code value
125# indicating 3
126#
127# verify: server displays received information
128#
129# check: Server sends response containing Code=68(2.04 Changed), same
130# Message ID as that of the previous request
131#
132# verify: client displays received response
133#
134function TD_COAP_CORE_03 {
135  clientopts="$callopts -m put -t 0 -e sometext"
136  testaddress=coap://$SERVERTUP/test
137  echo "perform PUT (CON) on resource $testaddress"
138  start_coap_test $1
139}
140
141##
142# Perform DELETE transaction (CON mode) on resource /test
143#
144# pre: resource /test exists which can handle DELETE
145#
146# Client sends a DELETE request with Type=0(CON), Code=4(DELETE)
147#
148# check: sent request contains Type value indicating 0 and Code value
149# indicating 4
150#
151# check: Server sends response containing Code=66(2.02 Deleted), same
152# Message ID as that of the previous request
153#
154# verify: client displays received response
155#
156function TD_COAP_CORE_04 {
157  clientopts="$callopts -m delete"
158  testaddress=coap://$SERVERTUP/test
159  echo "perform DELETE (CON) on resource $testaddress"
160  start_coap_test $1
161}
162
163##
164# Perform GET transaction (NON mode) on resource /test
165#
166# pre: resource /test exits which can handle GET
167#
168# Client sends a GET request with Type=1(NON), Code=1(GET)
169#
170# check: sent request contains Type value indicating 1 and Code value
171# indicating 1
172#
173# check: Server sends response containing Type=1(NON), Code=69(2.05
174# Content), content type option
175#
176# verify: client displays received response
177#
178function TD_COAP_CORE_05 {
179  # -N: send non-confirmable message
180  clientopts="$callopts -m get -N"
181  testaddress=coap://$SERVERTUP/test
182  echo "perform GET (NON mode) on resource $testaddress"
183  start_coap_test $1
184}
185
186##
187# Perform POST transaction (NON mode), create resource on /test
188#
189# pre: resource on /test doesn't exist but can be created
190#
191# Client sends a POST request with Type=1(NON), Code=2(POST),
192# arbitrary payload, content type option
193#
194# check: sent request contains Type value indicating 1 and Code value
195# indicating 2
196#
197# verify: Server displays the received information
198#
199# check: Server sends response containing Type=1(NON), Code=65(2.01
200# Created)
201#
202# verify: client displays received response
203#
204function TD_COAP_CORE_06 {
205  clientopts="$callopts -m post -t 0 -e sometext -N"
206  testaddress=coap://$SERVERTUP/test
207  echo "perform POST (NON) on resource $testaddress"
208  start_coap_test $1
209}
210
211##
212# Perform PUT transaction (NON mode) on resource /test
213#
214# pre: /test exists and can handle PUT
215#
216# Client sends a PUT request with Type=1(NON), Code=3(PUT),
217# arbitrary payload, content type option
218#
219# check: sent request contains Type value indicating 1 and Code value
220# indicating 3
221#
222# verify: Server displays the received information
223#
224# check: Server sends response containing Type=1(NON), Code=68(2.04
225# Changed)
226#
227# verify: client displays received response
228#
229function TD_COAP_CORE_07 {
230  clientopts="$callopts -m put -t 0 -e sometext -N"
231  testaddress=coap://$SERVERTUP/test
232  echo "perform PUT (NON) on resource $testaddress"
233  start_coap_test $1
234}
235
236##
237# Perform DELETE transaction (NON mode) on resource /test
238#
239# pre: /test exists and can handle DELETE
240#
241# Client sends a DELETE request with Type=1(NON), Code=4(DELETE)
242#
243# check: sent request contains Type value indicating 1 and Code value
244# indicating 4
245#
246# check: Server sends response containing Type=1(NON), Code=66(2.02
247# Deleted)
248#
249# verify: client displays received response
250#
251function TD_COAP_CORE_08 {
252  clientopts="$callopts -m delete -N"
253  testaddress=coap://$SERVERTUP/test
254  echo "perform DELETE (NON) on resource $testaddress"
255  start_coap_test $1
256}
257
258##
259# Perform GET transaction with a separate response on resource /separate
260#
261# pre: resource /separate exists which cannot be served immediately and which
262# cannot be acknowledged in a piggy-backed way
263#
264# Client sends a confirmable GET request to server's resource
265#
266# check: sent request contains Type=0(CON), Code=1(GET), client
267# generated Message ID
268#
269# check: Server sends response containing Type=2(ACK), message ID same
270# as the request, empty Payload
271#
272# check: Server sends response containing Type=0(CON), Code=69(2.05
273# content), Payload=Content of the requested resource, Content type option
274#
275# check: Client sends response containing Type=2(ACK), message ID same
276# as the response, empty Payload
277#
278# verify: client displays received response
279#
280function TD_COAP_CORE_09 {
281  clientopts="$callopts -m get"
282  testaddress=coap://$SERVERTUP/separate
283  echo "perform GET (CON) on resource $testaddress which cannot be served immediately"
284  start_coap_test $1
285}
286
287##
288# Perform GET transaction with Token on resource /test
289#
290# pre: resource /test exists which can handle GET requests
291#
292# Client sends a confirmable GET request to server's resource
293# including Token option
294#
295# check: sent request contains Type=0(CON) and Code=1(GET), client
296# generated Token value, length of the token which should be between 1
297# to 8 B, Option Type=Token
298#
299# check: Server sends response containing Code=69(2.05 content),
300# length of the token should be between 1 to 8 B, Token value same as
301# the requested, Payload=Content of the requested resource, Content
302# type option
303#
304# verify: client displays received response
305#
306function TD_COAP_CORE_10 {
307  clientopts="$callopts -m get -T sometok"
308  testaddress=coap://$SERVERTUP/test
309  echo "perform GET (CON) on resource $testaddress with Token"
310  start_coap_test $1
311}
312
313##
314# Perform GET transaction without Token on resource /test
315#
316# pre: resource /test exists which can handle GET requests
317#
318# Client sends a confirmable GET request to server's resource
319# not containing Token option
320#
321# check: sent request contains Type=0(CON) and Code=1(GET), no Token
322# option
323#
324# check: Server sends response containing Code=69(2.05 content), no
325# Token option, Payload=Content of the requested resource, Content
326# type option
327#
328# verify: client displays received response
329#
330function TD_COAP_CORE_11 {
331  clientopts="$callopts -m get"
332  testaddress=coap://$SERVERTUP/test
333  echo "perform GET (CON mode) without Token on resource $testaddress"
334  start_coap_test $1
335}
336
337##
338# Perform GET transaction to resource /seg1/seg2/seg3
339#
340# pre: resource /seg1/seg2/seg3 exists on server
341#
342# Client sends a confirmable GET request to server's resource
343#
344# check: sent request contains Type=0(CON) and Code=1(GET), Option
345# type=URI-Path (one for each path segment)
346#
347# check: Server sends response containing Code=69(2.05 content),
348# Payload=Content of the requested resource, Content type option
349#
350# verify: client displays received response
351#
352function TD_COAP_CORE_12 {
353  clientopts="$callopts -m get"
354  testaddress=coap://$SERVERTUP/seg1/seg2/seg3
355  echo "perform GET (CON mode) on resource $testaddress"
356  start_coap_test $1
357}
358
359##
360# Perform GET transaction to resource /query
361#
362# pre: resource /query exists on server
363#
364# Client sends a confirmable GET request with three Query parameters
365# (e.g. ?first=1&second=2&third=3) to server's resource
366#
367# check: sent request contains Type=0(CON) and Code=1(GET), Option
368# type=URI-Query (More than one query parameter)
369#
370# check: Server sends response containing Type=0/2(Con/ACK),
371# Code=69(2.05 content), Payload=Content of the requested resource,
372# Content type option
373#
374# verify: client displays received response
375#
376function TD_COAP_CORE_13 {
377  clientopts="$callopts -m get"
378  testaddress=coap://$SERVERTUP/query
379  query="?first=1&second=2&third=3"
380  echo -e "perform GET (CON mode) on resource $testaddress with query $query"
381  testaddress=$testaddress$query
382  start_coap_test $1
383}
384
385##
386# Perform GET transaction to resource /test in lossy context
387#
388# pre: gateway is introduced and configured to produce packet loss,
389# resource /test exists on server
390#
391# Configuration=CoAP_CFG_02
392#
393# observe: One dropped request, one dropped request ACK, one dropped
394# response, one dropped response ACK and its retransmission, test
395# sequence should be executed several times
396#
397# Client sends a confirmable GET request to server's resource
398#
399# check: sent request contains Type=0(CON) and Code=1(GET), Client
400# generated Message ID
401#
402# check: Server sends response containing Type=2(ACK), Code=69(2.05
403# content), Payload=Content of the requested resource, Content type
404# option
405#
406# verify: client displays received response
407#
408function TD_COAP_CORE_14 {
409  clientopts="$callopts -m get"
410  #FIXME: address for lossy context?
411  testaddress=coap://$SERVERTUP/test
412  echo "perform GET (CON mode) on resource $testaddress in lossy context"
413  start_coap_test $1
414}
415
416##
417# Perform GET transaction to resource /separate in lossy context
418#
419# pre: gateway is introduced and configured to produce packet loss,
420# resource /separate exists which cannot be served immediately and
421# which cannot be acknowledged in a piggy-backed way
422#
423# Configuration=CoAP_CFG_02
424#
425# observe: One dropped request, one dropped request ACK, one dropped
426# response, one dropped response ACK and its retransmission, test
427# sequence should be executed several times
428#
429# Client sends a confirmable GET request to server's resource
430#
431# check: sent request contains Type=0(CON) and Code=1(GET), Client
432# generated Message ID
433#
434# check: server sends response containing Type=2(ACK), Message ID same
435# as the request, empty Payload
436#
437# check: Server sends response containing Type=0(CON), Code=69(2.05
438# content), Payload=Content of the requested resource, Content type
439# option
440#
441# check: Client sends response containing Type=2(ACK), message ID same
442# as the response, empty Payload
443#
444# verify: client displays received response
445#
446function TD_COAP_CORE_15 {
447  clientopts="$callopts -m get"
448  #FIXME: address for lossy context?
449  testaddress=coap://$SERVERTUP/separate
450  echo "perform GET (CON mode) on resource $testaddress in lossy context"
451  start_coap_test $1
452}
453
454### LINK ###
455
456##
457# Access to well-known interface for resource discovery
458#
459# Pre: client supports CoRE Link Format, server supports
460# /.well-known/core resource and the CoRE Link Format
461#
462# Client retrieves Server's list of resource
463#
464# check: client sends GET request for /.well-known/core resource
465#
466# check: server sends response containing content-type option
467# indicating 40 (application/link-format), payload indicating all the
468# links available on Server
469#
470# client displays the list of resources available on Server
471#
472function TD_COAP_LINK_01 {
473  clientopts="$callopts -m get"
474  testaddress=coap://$SERVERTUP/.well-known/core
475  echo "retrieve server's list of resource"
476  start_tcpdump $1
477  if [ $verbose ]; then
478    echo "client command: $COAP_CLIENT $clientopts $testaddress"
479  fi
480  clientoutput=$($COAP_CLIENT $clientopts "$testaddress")
481  if [[ ! $(echo $clientoutput | grep rt) ]] ; then
482    echo "no resource with attribute rt found on server"
483  else
484    rt="${clientoutput##*rt=\"}"
485    rt="${rt%%\";*}"
486  fi
487  echo -e "\nOutput of client:"
488  echo -e $clientoutput
489  echo
490  kill_tcpdump
491}
492
493##
494# Use filtered requests for limiting discovery results
495#
496# Pre: client supports CoRE Link Format, server supports CoRE Link
497# Format and offers different types of resources (Type 1, Type 2
498# (extracted from /.well-knwon/core resource
499#
500# Client retrieves Server's list of resource of a specific Type 1
501#
502# check: client sends GET request for /.well-known/core resource
503# containing URI-Query indicating "rt=Type1"
504#
505# check: server sends response containing content-type option
506# indicating 40 (application/link-format), payload indicating only the
507# links of type Type1 available on server
508#
509# client displays the list of resources of type Type1 available on Server
510#
511function TD_COAP_LINK_02 {
512  clientopts="$callopts -m get"
513  echo "retrieve server's list of resource for appropriate type"
514  if [[ ! -z $rt ]]; then
515    testaddress="coap://$SERVERTUP/.well-known/core?rt=$rt"
516  else
517    echo "no appropriate resource found. Skipping test"
518    return
519  fi
520  start_coap_test $1
521}
522
523### BLOCK ###
524
525##
526# Perform GET blockwise transfer for large resource (early negotiation)
527#
528# pre: Client supports Block transfers, Server supports Block
529# transfers, Server offers a large resource /large, client knows
530# /large requires block transfer
531#
532# Client is requested to retrieve resource /large
533#
534# check: client sends a GET request containing Block2 option indicating block
535# number 0 and desired block size
536#
537# check: Each request contains Block2 option indicating block number
538# of the next block and size of the last received block
539#
540# check: server sends further responses containing Block2 option
541# indicating block number and size
542#
543# verify: client displays received response
544#
545function TD_COAP_BLOCK_01 {
546  clientopts="$callopts -m get -b 1024"
547  testaddress=coap://$SERVERTUP/large
548  echo "perform GET on large resource $testaddress (early negotiation)"
549  start_coap_test $1
550}
551
552##
553# Perform GET blockwise transfer for large resource (late negotiation)
554#
555# pre: Client supports Block transfers, Server supports Block
556# transfers, Server offers a large resource /large, client does not
557# know /large requires block transfer
558#
559# Client is requested to retrieve resource /large
560#
561# check: client sends a GET request not containing Block2 option
562#
563# check: server sends response containing Block2 option indicating
564# block number and size
565#
566# check: Each request contains Block2 option indicating block number
567# of the next block and size of the last received block or the desired
568# size of the next block
569#
570# check: server sends further responses containing Block2 option
571# indicating block number and size
572#
573# verify: client displays received response
574#
575function TD_COAP_BLOCK_02 {
576  clientopts="$callopts -m get"
577  testaddress=coap://$SERVERTUP/large
578  echo "perform GET blockwise transfer for large resource (late negotiation) on resource $testaddress"
579  start_coap_test $1 stop
580}
581
582##
583# Perform PUT blockwise transfer for large resource
584#
585# pre: Client supports Block transfers, Server supports Block
586# transfers, Server offers a large updatable resource /large-update
587#
588# Client is requested to retrieve resource /large-update on server
589#
590# check: client sends a PUT request containing Block1 option
591# indicating block number 0 and block size
592#
593# check: client sends further request containing Block1 option
594# indicating block number and size
595#
596# verify: server indicates presence of the complete updated resource
597# /large-update
598#
599function TD_COAP_BLOCK_03 {
600  clientopts="$callopts -m put -b 1024"
601  testaddress=coap://$SERVERTUP/large-update
602  echo "perform PUT on large resource $testaddress"
603  start_coap_test $1
604}
605
606##
607# Perform POST blockwise transfer for large resource
608#
609# pre: Client supports Block transfers, Server supports Block
610# transfers, Server accepts creation of new resources on /large-create
611#
612# Client is requested to create a new resource on server
613#
614# check: client sends a POST request containing Block1 option
615# indicating block number 0 and block size
616#
617# check: client sends further requests containing Block1 option
618# indicating block number and size
619#
620# verify: server indicates presence of the complete new resource
621#
622function TD_COAP_BLOCK_04 {
623  clientopts="$callopts -m post -b 1024"
624  testaddress=coap://$SERVERTUP/large-create
625  echo "perform POST on large resource $testaddress"
626  start_coap_test $1
627}
628
629# # OBS
630
631##
632# Handle observe option
633#
634# pre: client supports Observe option, server supports observe option,
635# server offers an observable resource /obs which changes periodically
636# (e.g. every 5s.)
637#
638# client is requested to observe resource /obs on server
639#
640# check: client sends a GET request containing observe option
641#
642# verify: client displays the received information
643#
644# check: server sends response containing observe option indicating
645# increasing values, as resource changes
646#
647# verify: client displays the updated information
648#
649function TD_COAP_OBS_01 {
650  # we need some time to verify the correct behavior
651  clientopts="$callopts -s 0" #"-v 5 -B $longtimeout -s 0"
652  testaddress=coap://$SERVERTUP/obs
653  echo "observe resource $testaddress"
654  start_coap_test $1
655}
656
657##
658# Stop resource observation
659#
660# pre: client supports Observe option, server supports observe option,
661# server offers an observable resource /obs which changes periodically
662# (e.g. every 5s.), client is observing /obs on server
663#
664# client is requested to stop observing resource /obs on server
665#
666# check: client sends a GET request not containing observe option
667#
668# verify: client displays the received information
669#
670# check: server does not send further response
671#
672# verify: client does not display the updated information
673#
674# function TD_COAP_OBS_02 {
675#   #FIXME: client does not support stopping yet
676  # we need some time to verify the correct behavior
677#   clientopts="-v 5 -B $longtimeout -s 1"
678#   testaddress=coap://$SERVERTUP/obs
679#   echo "stop observing resource $testaddress"
680#   start_coap_test $1
681# }
682
683##
684# client detection of deregistration (Max-Age)
685#
686# pre: client supports Observe option, server supports observe option,
687# server offers an observable resource /obs which changes periodically
688# (e.g. every 5s.), client is observing /obs on server
689#
690# Server is rebooted
691#
692# check: Server does not send notifications
693#
694# verify: Client does not display updated information
695#
696# verify: After Max-Age expiration, client sends a new GET with observe
697# option for Server's observable resource
698#
699# check: Sent request contains Observe option indicating 0
700#
701# check: Server sends response containing Observe option
702#
703# verify: client displays the received information
704#
705# check: Server sends response containing Observe option indicating
706# increasing values, as resource changes
707#
708# verify: Client displays the updated information
709#
710function TD_COAP_OBS_03 {
711  clientopts="$callopts -s 0"#"-v5 -B $longtimeout -s 0"
712  testaddress=coap://$SERVERTUP/obs
713  echo "client detection of deregistration (Max-Age)"
714  start_coap_test $1
715}
716
717##
718# Server detection of deregistration (client OFF)
719#
720# pre: client supports Observe option, server supports observe option,
721# server offers an observable resource /obs which changes periodically
722# (e.g. every 5s.), client is observing /obs on server
723#
724# Client is switched off
725#
726# check: Server’s confirmable responses are not acknowledged
727#
728# verify: After some delay, Server does not send further responses
729#
730function TD_COAP_OBS_04 {
731  clientopts="$callopts -s 0"
732#"-v 5 -B $longtimeout -s 0"
733  testaddress=coap://$SERVERTUP/obs
734  echo "server detection of deregistration (client off)"
735  start_coap_test $1 wait
736}
737
738##
739# Server detection of deregistration (explicit RST)
740#
741# pre: client supports Observe option, server supports observe option,
742# server offers an observable resource /obs which changes periodically
743# (e.g. every 5s.), client is observing /obs on server
744#
745# Client is rebooted
746#
747# check: Server sends response containing Observe option
748#
749# verify: Client discards response and does not display information
750#
751# check: Client sends RST to Server
752#
753# check: Server does not send further response
754#
755function TD_COAP_OBS_05 {
756  clientopts="$callopts -s 0 -p $CLIENTPORT"
757#"-v 5 -B $longtimeout -p $CLIENTPORT -s 0"
758  testaddress=coap://$SERVERTUP/obs
759  echo "server detection of deregistration (explicit RST)"
760  start_coap_test $1 stop
761  clientopts="$callopts -p $CLIENTPORT -s 0 -N"
762#"-v 5 -B $clienttimeout -p $CLIENTPORT -s 0 -N"
763  testaddress=coap://[::1]/obs
764  start_coap_test $1
765}