#!/usr/bin/env python
import getopt
import socket
import sys
import cbor
#from cbor2 import dumps, loads
import json
import time
import traceback

from coapthon.client.helperclient import HelperClient
from coapthon.utils import parse_uri
from coapthon import defines

client = None
paths = {}
paths_extend = {}

my_base = ""


def usage():  # pragma: no cover
    print("Command:\tknxcoapclient.py -o -p [-P]")
    print("Options:")
    print("\t-o, --operation=\tGET|GETNONE|PUT|POST|DELETE|DISCOVER|OBSERVE")
    print("\t-p, --path=\t\t\tPath of the request")
    print("\t-P, --payload=\t\tPayload of the request")
    print("\t-c, --contenttype=\t\tcontenttype of the request")
    print("\t-f, --payload-file=\t\tFile with payload of the request")


def get_url(line):
    data = line.split(">")
    url = data[0]
    return url[1:]

def get_ct(line):
    tagvalues = line.split(";")
    for tag in tagvalues:
       if tag.startswith("ct"):
          ct_value_all = tag.split("=")
          ct_value = ct_value_all[1].split(",")
          return ct_value[0]
    return ""

def get_base(url):
    # python3 knxcoapclient.py -o GET -p coap://[fe80::6513:3050:71a7:5b98]:63914/a -c 50
    my_url = url.replace("coap://","")
    mybase = my_url.split("/")
    return mybase[0]


def get_base_from_link(payload):
    print("get_base_from_link\n")
    global paths
    global paths_extend
    lines = payload.splitlines()
    
    # add the 
    if len(paths) == 0:
        my_base = get_base(get_url(lines[0]))
        return my_base
        

def get_sn(my_base):
    print("Get SN :");
    sn = execute_get("coap://"+my_base+"/dev/sn", 60)
    json_data = cbor.loads(sn.payload)
    #print ("SN : ", json_data)
    return json_data

def install(my_base):
    sn = get_sn(my_base)
    print (" SN : ", sn)
    iid = "5"  # installation id
    if "000001" == sn :
       # sensor, e.g sending  
       print ("--------------------")
       print ("Installing SN: ", sn)
       
       content = { 2: "reset"}
       print("reset :", content);
       execute_post("coap://"+my_base+"/.well-known/knx", 60, 60, content)
       
       content = True
       print("set PM :", content);
       execute_put("coap://"+my_base+"/dev/pm", 60, 60, content)
       content = 1
       print("set IA :", content);
       execute_put("coap://"+my_base+"/dev/ia", 60, 60, content)
       content = iid
       execute_put("coap://"+my_base+"/dev/iid", 60, 60, content)
       
       
       content = { 2: "startLoading"}
       print("lsm :", content);
       execute_post("coap://"+my_base+"/a/lsm", 60, 60, content)
       execute_get("coap://"+my_base+"/a/lsm", 60)
       # group object table
       # id (0)= 1
       # url (11)= /p/light
       # ga (7 )= 1
       # cflags (8) = ["r" ] ; read = 1, write = 2, transmit = 3 update = 4
       content = [ {0: 1, 11: "p/push", 7:[1], 8: [2] } ] 
       execute_post("coap://"+my_base+"/fp/g", 60, 60, content)
       
       execute_get("coap://"+my_base+"/fp/g", 40)
       
       
       # recipient table
       # id (0)= 1
       # ia (12)
       # url (11)= .knx
       # ga (7 )= 1
       # cflags (8) = ["r" ] ; read = 1, write = 2, transmit = 3 update = 4
       content = [ {0: 1, 11: "/p/push", 7:[1], 12 :"blah.blah" } ] 
       execute_post("coap://"+my_base+"/fp/r", 60, 60, content)
       
       content = False
       print("set PM :", content);
       execute_put("coap://"+my_base+"/dev/pm", 60, 60, content)
       
       content = { 2: "loadComplete"}
       print("lsm :", content);
       execute_post("coap://"+my_base+"/a/lsm", 60, 60, content)
       execute_get("coap://"+my_base+"/a/lsm", 60)
       
       
    if "000002" == sn :
       # actuator ==> receipient
       # should use /fp/r
       print ("--------------------")
       print ("installing SN: ", sn)
       content = True
       print("set PM :", content);
       execute_put("coap://"+my_base+"/dev/pm", 60, 60, content)
       content = 2
       print("set IA :", content);
       execute_put("coap://"+my_base+"/dev/ia", 60, 60, content)
       content = iid
       execute_put("coap://"+my_base+"/dev/iid", 60, 60, content)
       
       
       content = { 2: "startLoading"}
       print("lsm :", content);
       execute_post("coap://"+my_base+"/a/lsm", 60, 60, content)
       execute_get("coap://"+my_base+"/a/lsm", 60)
       
       # group object table
       # id (0)= 1
       # url (11)= /p/light
       # ga (7 )= 1
       # cflags (8) = ["r" ] ; read = 1, write = 2, transmit = 3 update = 4
       content = [ { 0: 1, 11: "/p/light", 7:[1], 8: [1] } ] 
       execute_post("coap://"+my_base+"/fp/g", 60, 60, content)
       
       execute_get("coap://"+my_base+"/fp/g", 40)
       # publisher table
       # id (0)= 1
       # ia (12)
       # url (11)= .knx
       # ga (7 )= 1
       # cflags (8) = ["r" ] ; read = 1, write = 2, transmit = 3 update = 4
       content = [ {0: 1, 11: ".knx", 7:[1], 12 :"blah.blah" } ] 
       execute_post("coap://"+my_base+"/fp/p", 60, 60, content)
       
       content = False
       print("set PM :", content);
       execute_put("coap://"+my_base+"/dev/pm", 60, 60, content)
       
       content = { 2: "loadComplete"}
       print("lsm :", content);
       execute_post("coap://"+my_base+"/a/lsm", 60, 60, content)
       execute_get("coap://"+my_base+"/a/lsm", 60)
       
       

    # do a post
    content = {"sia": 5678, "st": 55, "ga": 1, "value": 100 }
    content = { 4: 5678, "st": 55, 7: 1, "value": 100 }
    #                 st       ga       value (1)
    #content = { 5: { 6: 1, 7: 1, 1: True } } 
    #execute_post("coap://"+my_base+"/.knx", 60, 60, content)
    
    content = {4: 5678, 5: { 6: 1, 7: 1, 1: False } } 
    #execute_post("coap://"+my_base+"/.knx", 60, 60, content)
    #execute_post("coap://[FF02::FD]:5683/.knx", 60, 60, content)
    


# no json tags as strings
def do_sequence_dev(my_base):

    print("===================")
    print("Get SN :");
    sn = execute_get("coap://"+my_base+"/dev/sn", 60)
    sn = get_sn(my_base)
    print (" SN : ", sn)
   

    print("===================")
    print("Get HWT :");
    execute_get("coap://"+my_base+"/dev/hwt", 60)
    
    print("===================")
    print("Get HWV :");
    execute_get("coap://"+my_base+"/dev/hwv", 60)

    print("===================")
    print("Get FWV :");
    execute_get("coap://"+my_base+"/dev/fwv", 60)

    print("===================")
    print("Get Model :");
    execute_get("coap://"+my_base+"/dev/model", 60)

    print("===================")
    content = True
    print("set PM :", content);
    execute_put("coap://"+my_base+"/dev/pm", 60, 60, content)
    execute_get("coap://"+my_base+"/dev/pm", 60)
    content = False
    print("set PM :", content);
    execute_put("coap://"+my_base+"/dev/pm", 60, 60, content)
    execute_get("coap://"+my_base+"/dev/pm", 60)
    
    print("===================")
    content = 44
    print("set IA :", content);
    execute_put("coap://"+my_base+"/dev/ia", 60, 60, content)
    execute_get("coap://"+my_base+"/dev/ia", 60)
    
    print("===================")
    content = "my host name"
    print("set hostname :", content);
    execute_put("coap://"+my_base+"/dev/hostname", 60, 60, content)
    execute_get("coap://"+my_base+"/dev/hostname", 60)
    
    
    print("===================")
    content = " iid xxx"
    print("set iid :", content);
    execute_put("coap://"+my_base+"/dev/iid", 60, 60, content)
    execute_get("coap://"+my_base+"/dev/iid", 60)



# id ==> 0
# href ==> 11
# ga ==> 7
# cflag ==> 8
def do_sequence_fp_g_int(my_base):

    #  url, content, accept, contents
    content = [ {0: 1, 11: "xxxx1", 8: [1,2,3,4,5], 7:[2222,3333]} ] 
    execute_post("coap://"+my_base+"/fp/g", 60, 60, content)
    execute_get("coap://"+my_base+"/fp/g/1", 60)
    execute_get("coap://"+my_base+"/fp/g", 40)
    content = [ {0: 2, 11: "xxxxyyy2", 8: [1,4,5], 7:[44,55,33]}, {0: 3, 1: "xxxxyyy3", 8: [1,4,5], 7:[44,55,33]} ] 
    execute_post("coap://"+my_base+"/fp/g", 60, 60, content)
    execute_get("coap://"+my_base+"/fp/g/2", 60)
    execute_get("coap://"+my_base+"/fp/g/3", 60)
    execute_get("coap://"+my_base+"/fp/g", 40)
    
    execute_del("coap://"+my_base+"/fp/g/3", 60)
    execute_get("coap://"+my_base+"/fp/g/3", 60)
    execute_get("coap://"+my_base+"/fp/g", 40)

def do_sequence_fp_g(my_base):

    #  url, content, accept, contents
    content = [ {"id": 1, "href": "xxxx1", "cflag": [1,2,3,4,5], "ga":[2222,3333]} ] 
    execute_post("coap://"+my_base+"/fp/g", 60, 60, content)
    execute_get("coap://"+my_base+"/fp/g/1", 60)
    execute_get("coap://"+my_base+"/fp/g", 40)
    content = [ {"id": 2, "href": "xxxxyyy2", "cflag": [1,4,5], "ga":[44,55,33]}, {"id": 3, "href": "xxxxyyy3", "cflag": [1,4,5], "ga":[44,55,33]} ] 
    execute_post("coap://"+my_base+"/fp/g", 60, 60, content)
    execute_get("coap://"+my_base+"/fp/g/2", 60)
    execute_get("coap://"+my_base+"/fp/g/3", 60)
    execute_get("coap://"+my_base+"/fp/g", 40)
    
    execute_del("coap://"+my_base+"/fp/g/3", 60)
    execute_get("coap://"+my_base+"/fp/g/3", 60)
    execute_get("coap://"+my_base+"/fp/g", 40)
    
        
# id ==> 0
# ia ==> 12
# path ==> 112
# url ==> 10
# ga ==> 7
def do_sequence_fp_p_int(my_base):

    #  url, content, accept, contents
    content = [ {0: 1, 12: "Ia.IA1", 112: "path1", 7:[2222,3333]} ] 
    execute_post("coap://"+my_base+"/fp/p", 60, 60, content)
    execute_get("coap://"+my_base+"/fp/p/1", 60)
    # 40 == application-link format
    execute_get("coap://"+my_base+"/fp/p", 40)
    content = [ {0: 2, 12: "xxxxyyyia2", 112: "path2", 7:[44,55,33]}, 
                {0: 3, 12: "xxxxyyyia3", 112: "path3", 7:[44,55,33]} ] 
    execute_post("coap://"+my_base+"/fp/p", 60, 60, content)
    execute_get("coap://"+my_base+"/fp/p/2", 60)
    execute_get("coap://"+my_base+"/fp/p/3", 60)
    execute_get("coap://"+my_base+"/fp/p", 40)
    
    execute_del("coap://"+my_base+"/fp/p/3", 60)
    execute_get("coap://"+my_base+"/fp/p/3", 60)
    execute_get("coap://"+my_base+"/fp/p", 40)

def do_sequence_fp_p(my_base):

    #  url, content, accept, contents
    content = [ {"id": 1, "ia": "Ia.IA1", "path": "path1", "ga":[2222,3333]} ] 
    execute_post("coap://"+my_base+"/fp/p", 60, 60, content)
    execute_get("coap://"+my_base+"/fp/p/1", 60)
    # 40 == application-link format
    execute_get("coap://"+my_base+"/fp/p", 40)
    content = [ {"id": 2, "ia": "xxxxyyyia2", "path": "path2","ga":[44,55,33]}, {"id": 3, "ia": "xxxxyyyia3", "path": "path3","ga":[44,55,33]} ] 
    execute_post("coap://"+my_base+"/fp/p", 60, 60, content)
    execute_get("coap://"+my_base+"/fp/p/2", 60)
    execute_get("coap://"+my_base+"/fp/p/3", 60)
    execute_get("coap://"+my_base+"/fp/p", 40)
    
    execute_del("coap://"+my_base+"/fp/p/3", 60)
    execute_get("coap://"+my_base+"/fp/p/3", 60)
    execute_get("coap://"+my_base+"/fp/p", 40)



# id ==> 0
# ia ==> 12
# path ==> 112
# url ==> 10
# ga ==> 7
def do_sequence_fp_r_int(my_base):

    #  url, content, accept, contents
    content = [ { 0: 1, 12: "r-Ia.IA1", 112: "r-path1", 7:[2222,3333]}  ] 
    execute_post("coap://"+my_base+"/fp/r", 60, 60, content)
    execute_get("coap://"+my_base+"/fp/r/1", 60)
    execute_get("coap://"+my_base+"/fp/r", 40)
    content = [ { 0: 2, 12: "r-Ia.IA2", 10: "url2", 112: "r-path2", 7:[44,55,33]}, 
                {0: 3, 12: "r-Ia.IA3", 112: "r-path3", 7:[44,55,33]} ] 
    execute_post("coap://"+my_base+"/fp/r", 60, 60, content)
    execute_get("coap://"+my_base+"/fp/r/2", 60)
    execute_get("coap://"+my_base+"/fp/r/3", 60)
    execute_get("coap://"+my_base+"/fp/r", 40)
    
    execute_del("coap://"+my_base+"/fp/r/3", 60)
    execute_get("coap://"+my_base+"/fp/r/3", 60)
    execute_get("coap://"+my_base+"/fp/r", 40)

def do_sequence_fp_r(my_base):

    #  url, content, accept, contents
    content = [ {"id": 1, "ia": "r-Ia.IA1", "path": "r-path1", "ga":[2222,3333]}  ] 
    execute_post("coap://"+my_base+"/fp/r", 60, 60, content)
    execute_get("coap://"+my_base+"/fp/r/1", 60)
    execute_get("coap://"+my_base+"/fp/r", 40)
    content = [ {"id": 2, "ia": "r-Ia.IA2", "path": "r-path2", "ga":[44,55,33]}, {"id": 3, "ia": "r-Ia.IA3", "path": "r-path3", "ga":[44,55,33]} ] 
    execute_post("coap://"+my_base+"/fp/r", 60, 60, content)
    execute_get("coap://"+my_base+"/fp/r/2", 60)
    execute_get("coap://"+my_base+"/fp/r/3", 60)
    execute_get("coap://"+my_base+"/fp/r", 40)
    
    execute_del("coap://"+my_base+"/fp/r/3", 60)
    execute_get("coap://"+my_base+"/fp/r/3", 60)
    execute_get("coap://"+my_base+"/fp/r", 40)


# cmd ==> 2
def do_sequence_lsm_int(my_base):

    #  url, content, accept, contents

    execute_get("coap://"+my_base+"/a/lsm", 60)
    
    content = {2 : "startLoading"}
    execute_post("coap://"+my_base+"/a/lsm", 60, 60, content)
    execute_get("coap://"+my_base+"/a/lsm", 60)
    
    content = {2 : "loadComplete"}
    execute_post("coap://"+my_base+"/a/lsm", 60, 60, content)
    execute_get("coap://"+my_base+"/a/lsm", 60)
    
    content = {2 : "unload"}
    execute_post("coap://"+my_base+"/a/lsm", 60, 60, content)
    execute_get("coap://"+my_base+"/a/lsm", 60)

def do_sequence_lsm(my_base):

    #  url, content, accept, contents

    execute_get("coap://"+my_base+"/a/lsm", 60)
    
    content = {"cmd": "startLoading"}
    execute_post("coap://"+my_base+"/a/lsm", 60, 60, content)
    execute_get("coap://"+my_base+"/a/lsm", 60)
    
    content = {"cmd": "loadComplete"}
    execute_post("coap://"+my_base+"/a/lsm", 60, 60, content)
    execute_get("coap://"+my_base+"/a/lsm", 60)
    
    content = {"cmd": "unload"}
    execute_post("coap://"+my_base+"/a/lsm", 60, 60, content)
    execute_get("coap://"+my_base+"/a/lsm", 60)


# ./knx resource
# sia ==> 4
# ga ==> 7
# st 6 
def do_sequence_knx_knx_int(my_base):

    #  url, content, accept, contents
    execute_get("coap://"+my_base+"/.knx", 60)
    content = {"value": { 4 : 5, 7: 7777 , 6 : "rp"}}
    execute_post("coap://"+my_base+"/.knx", 60, 60, content)
    execute_get("coap://"+my_base+"/.knx", 60)

# ./knx resource
def do_sequence_knx_knx(my_base):

    #  url, content, accept, contents
    execute_get("coap://"+my_base+"/.knx", 60)
    content = {"value": { "sia" : 5, "ga": 7, "st": "rp"}}
    execute_post("coap://"+my_base+"/.knx", 60, 60, content)
    execute_get("coap://"+my_base+"/.knx", 60)


def do_sequence_knx_spake(my_base):

    #  url, content, accept, contents
    
    # sequence:
    # - parameter exchange: 15 (rnd)- return value
    # - credential exchange: 10 - return value
    # - pase verification exchange: 14  - no return value
    
    content = { 15: b"a-15-sdfsdred"}
    execute_post("coap://"+my_base+"/.well-known/knx/spake", 60, 60, content)
    
    # pa
    content = { 10: b"s10dfsdfsfs" }
    execute_post("coap://"+my_base+"/.well-known/knx/spake", 60, 60, content)
    
    # ca
    content = { 14: b"a15sdfsdred"}
    execute_post("coap://"+my_base+"/.well-known/knx/spake", 60, 60, content)
    # expecting return 
    

def do_sequence_knx_idevid(my_base):
    #  url, content, accept, contents
    execute_get("coap://"+my_base+"/.well-known/knx/idevid", 282)
    
def do_sequence_knx_ldevid(my_base):
    #  url, content, accept, contents
    execute_get("coap://"+my_base+"/.well-known/knx/ldevid", 282)


def do_sequence_knx_osn(my_base):
    #  url, content, accept, contents
    execute_get("coap://"+my_base+"/.well-known/knx/osn", 60)


def do_sequence_knx_crc(my_base):
    #  url, content, accept, contents
    execute_get("coap://"+my_base+"/.well-known/knx/crc", 60)
    
    
def do_sequence_oscore(my_base):
    #  url, content, accept, contents
    execute_get("coap://"+my_base+"/f/oscore", 40)
    
    execute_get("coap://"+my_base+"/p/oscore/replwdo", 60)
    content = 105 
    execute_put("coap://"+my_base+"/p/oscore/replwdo", 60, 60, content)
    execute_get("coap://"+my_base+"/p/oscore/replwdo", 60)
    
    execute_get("coap://"+my_base+"/p/oscore/osndelay", 60)
    content =  1050
    execute_put("coap://"+my_base+"/p/oscore/osndelay", 60, 60, content)
    execute_get("coap://"+my_base+"/p/oscore/osndelay", 60)


def do_sequence_core_knx(my_base):
    #  url, content, accept, contents
    execute_get("coap://"+my_base+"/.well-known/knx", 60)
    content = { 1 : 5, 2: "reset"}
    execute_post("coap://"+my_base+"/.well-known/knx", 60, 60, content)
    
    
def do_sequence_a_sen(my_base):
    #  url, content, accept, contents
    content = {2: "reset"}
    execute_post("coap://"+my_base+"/a/sen", 60, 60, content)
    
    
def do_sequence_auth(my_base):
    #  url, content, accept, contents
    
    execute_get("coap://"+my_base+"/auth", 40)
    
    
def do_sequence_auth_at(my_base):
    #  url, content, accept, contents
    
    execute_get("coap://"+my_base+"/auth/at", 40)
    # 
    content = {0: b"id", 1 : 20, 2:b"ms",3:"hkdf", 4:"alg", 5:b"salt", 6:b"contextId"}
    execute_post("coap://"+my_base+"/auth/at", 60, 60, content)
    
    
    content = {0: b"id2", 1 : 20, 2:b"ms",3:"hkdf", 4:"alg", 5:b"salt", 6:b"contextId2"}
    execute_post("coap://"+my_base+"/auth/at", 60, 60, content)
    
    execute_get("coap://"+my_base+"/auth/at", 40)
    
    execute_get("coap://"+my_base+"/auth/at/id", 60)
    execute_del("coap://"+my_base+"/auth/at/id", 60)
    
    
def do_sequence_f(my_base):

    #  url, content, accept, contents
    execute_get("coap://"+my_base+"/f", 40)
    # note this one is a bit dirty hard coded...
    execute_get("coap://"+my_base+"/f/417", 40)
    execute_get("coap://"+my_base+"/.well-known/core", 40)
    

def do_sequence(my_base):
    
    #sn = get_sn(my_base)
    install(my_base)
    return
    do_sequence_dev(my_base)
    
    
    #return
    do_sequence_fp_g_int(my_base)
    #do_sequence_fp_g(my_base)
    
    do_sequence_fp_p_int(my_base)
    #do_sequence_fp_p(my_base)
    
    do_sequence_fp_r_int(my_base)
    #do_sequence_fp_r(my_base)
    
    do_sequence_lsm_int(my_base)
    #do_sequence_lsm(my_base)
    do_sequence_lsm_int(my_base)
    # .knx
    do_sequence_knx_knx_int(my_base)
    #do_sequence_knx_knx(my_base)
    
    do_sequence_knx_spake(my_base)
    do_sequence_knx_idevid(my_base)
    do_sequence_knx_ldevid(my_base)
    do_sequence_knx_crc(my_base)
    do_sequence_knx_osn(my_base)
    
    do_sequence_oscore(my_base)
    do_sequence_core_knx(my_base)
    
    do_sequence_a_sen(my_base)
    do_sequence_auth(my_base)
    do_sequence_auth_at(my_base)
    
    do_sequence_f(my_base)
    
        

def client_callback_discovery(response, checkdata=None):
    print(" --- Discovery Callback ---")
    global my_base
    if response is not None:
        print ("response code:",response.code)
        print ("response type:",response.content_type)
        if response.code > 100:
            print("+++returned error+++")
            return
        if response.content_type == defines.Content_types["application/link-format"]:
            print (response.payload.decode())
            my_base = get_base_from_link(response.payload.decode())
            do_sequence(my_base)

def code2string(code):
   if code == 68:
      return "(Changed)"
   if code == 69:
      return "(Content)"
   if code == 132:
      return "(Not Found)"
   if code == 133:
      return "(METHOD_NOT_ALLOWED)"
   if code == 160:
      return "(INTERNAL_SERVER_ERROR)"
   
   return ""


def client_callback(response, checkdata=None):
    print(" --- Callback ---")
    if response is not None:
        print ("response code:",response.code, code2string(response.code))
        print ("response type:",response.content_type)
        if response.code > 100:
            print("+++returned error+++")
            return
        #print(response.pretty_print())
        if response.content_type == defines.Content_types["text/plain"]:
            if response.payload is not None:
              print (type(response.payload), len(response.payload))
              print ("=========")
              print (response.payload)
              print ("=========")
            else: 
                print ("payload: none")
        elif response.content_type == defines.Content_types["application/cbor"]:
            print (type(response.payload), len(response.payload))
            print ("=========")
            print (response.payload)
            print ("=========")
            #json_data = loads(response.payload)
            #print(json_data)
            #print ("=========")
            json_string = ""
            try:
                json_data = cbor.loads(response.payload)
                json_string = json.dumps(json_data, indent=2, sort_keys=True)
            except:
                print("error in cbor..")
            print (json_string)
            print ("===+++===")
            if checkdata is not None:
               check_data = cbor.loads(checkdata)
               check_string = json.dumps(check_data, indent=2, sort_keys=True)
               print("  check: ")
               print (check_string)
               if check_string == json_string:
                  print("  =+++===> OK  ")
               else:
                  print("  =+++===> NOT OK  ")
            
            print (json_string)
        elif response.content_type == defines.Content_types["application/vnd.ocf+cbor"]:
            print ("application/vnd.ocf+cbor")
            try:
                print (type(response.payload), len(response.payload))
                print ("=========")
                print (response.payload)
                print ("=========")
                json_data = cbor.loads(response.payload)
                print (json_data)
                print ("---------")
            except:
                traceback.print_exc()
            json_string = json.dumps(json_data, indent=2, sort_keys=True)
            print (json_string)
        elif response.content_type == defines.Content_types["application/link-format"]:
            print (response.payload.decode())
        else:
            if response.payload is not None:
              print ("type, len", type(response.payload), len(response.payload))
              print (response.payload)
            #else:
            #    print ("    not handled: ", response)
    else:
        print (" Response : None")
    #check = True
    #while check:
    #    chosen = eval(input("Stop observing? [y/N]: "))
    #    if chosen != "" and not (chosen == "n" or chosen == "N" or chosen == "y" or chosen == "Y"):
    #        print("Unrecognized choose.")
    #        continue


def client_callback_observe(response):  # pragma: no cover
    global client
    print("Callback_observe")
    check = True
    while check:
        chosen = eval(input("Stop observing? [y/N]: "))
        if chosen != "" and not (chosen == "n" or chosen == "N" or chosen == "y" or chosen == "Y"):
            print("Unrecognized choose.")
            continue
        elif chosen == "y" or chosen == "Y":
            while True:
                rst = eval(input("Send RST message? [Y/n]: "))
                if rst != "" and not (rst == "n" or rst == "N" or rst == "y" or rst == "Y"):
                    print("Unrecognized choose.")
                    continue
                elif rst == "" or rst == "y" or rst == "Y":
                    client.cancel_observing(response, True)
                else:
                    client.cancel_observing(response, False)
                check = False
                break
        else:
            break


def execute_get(mypath, ct_value):
      print ("---------------------------")
      print ("execute_get: ", ct_value, mypath)
      print (type(mypath))
      
      if (mypath is None or len(mypath) < 5):
        return
      if mypath.startswith("coap://") == False:
        print(" not executing: ", mypath);
        return;

      ct = {}
      ct['accept'] = ct_value
      host, port, path = parse_uri(mypath)
      try:
        tmp = socket.gethostbyname(host)
        host = tmp
      except socket.gaierror:
        pass
      nclient = HelperClient(server=(host, port))
      response = nclient.get(path, None, None, **ct)
      client_callback(response)
      nclient.stop()
      return response

def execute_del(mypath, ct_value):
      print ("---------------------------")
      print ("execute_del: ", ct_value, mypath)
      do_exit = False
      ct = {}
      ct['accept'] = ct_value
      ct['content_type'] = ct_value
      
      if mypath.startswith("coap://") == False:
        print(" not executing: ", mypath);
        return;
      
      host, port, path = parse_uri(mypath)
      try:
        tmp = socket.gethostbyname(host)
        host = tmp
      except socket.gaierror:
        pass
      nclient = HelperClient(server=(host, port))
      nclientcheck = HelperClient(server=(host, port))
      payload = 0

      response = nclient.delete(path, None, None, **ct)
      client_callback(response)
        #nclient.stop()
        #sys.exit(2)
      print ("=======")



def execute_put(mypath, ct_value, accept, content):
      print ("---------------------------")
      print ("execute_put: ", ct_value, mypath)
      do_exit = False
      ct = {}
      ct['accept'] = accept
      ct['content_type'] = ct_value
      
      if mypath.startswith("coap://") == False:
        print(" not executing: ", mypath);
        return
      
      host, port, path = parse_uri(mypath)
      try:
        tmp = socket.gethostbyname(host)
        host = tmp
      except socket.gaierror:
        pass
      nclient = HelperClient(server=(host, port))
      nclientcheck = HelperClient(server=(host, port))
      payload = 0

      if accept == 60:
        payload = cbor.dumps(content)
      else:
        payload = content
      print ("payload: ", payload)
      response = nclient.put(path, payload, None, None , None, **ct)
      client_callback(response)
      nclient.stop()
      
      
def execute_post(mypath, ct_value, accept, content):
      print ("---------------------------")
      print ("execute_post: ", ct_value, mypath)
      print (content)
      print ("     ---------------------")
      do_exit = False
      ct = {}
      ct['accept'] = accept
      ct['content_type'] = ct_value
      
      if mypath.startswith("coap://") == False:
        print(" not executing: ", mypath);
        return
      
      host, port, path = parse_uri(mypath)
      try:
        tmp = socket.gethostbyname(host)
        host = tmp
      except socket.gaierror:
        pass
      nclient = HelperClient(server=(host, port))
      #nclientcheck = HelperClient(server=(host, port))
      payload = 0

      if accept == 60:
        #print(" content :", content)
        payload = cbor.dumps(content)
      else:
        payload = content
      response = nclient.post(path, payload, None, None , None, **ct)
      client_callback(response)
      nclient.stop()


def main():  # pragma: no cover
    global client
    op = None
    path = None
    payload = None
    content_type = None
    #ct = {'content_type': defines.Content_types["application/link-format"]}
    ct = {}
    ct['accept'] = 40
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ho:p:P:f:c:", ["help", "operation=", "path=", "payload=",
                                                               "payload_file=","content-type"])
    except getopt.GetoptError as err:
        # print help information and exit:
        print((str(err)))  # will print something like "option -a not recognized"
        usage()
        sys.exit(2)
    for o, a in opts:
        if o in ("-o", "--operation"):
            op = a
        elif o in ("-p", "--path"):
            path = a
        elif o in ("-P", "--payload"):
            payload = a
        elif o in ("-c", "--content-type"):
            ct['accept'] = a
            print ("content type request : ", ct)
        elif o in ("-f", "--payload-file"):
            with open(a, 'r') as f:
                payload = f.read()
        elif o in ("-h", "--help"):
            usage()
            sys.exit()
        else:
            usage()
            sys.exit(2)

    if op is None:
        print("Operation must be specified")
        usage()
        sys.exit(2)

    if path is None:
        print("Path must be specified")
        usage()
        sys.exit(2)

    if not path.startswith("coap://"):
        print("Path must be conform to coap://host[:port]/path")
        usage()
        sys.exit(2)

    host, port, path = parse_uri(path)
    try:
        tmp = socket.gethostbyname(host)
        host = tmp
    except socket.gaierror:
        pass
    client = HelperClient(server=(host, port))
    if op == "GET":
        if path is None:
            print("Path cannot be empty for a GET request")
            usage()
            sys.exit(2)
        response = client.get(path, None, None, **ct)
        print((response.pretty_print()))
        if response.content_type == defines.Content_types["application/json"]:
            json_data = json.loads(response.payload)
            json_string = json.dumps(json_data, indent=2, sort_keys=True)
            print ("JSON ::")
            print (json_string)
        if response.content_type == defines.Content_types["application/cbor"]:
            json_data = cbor.loads(response.payload)
            json_string = json.dumps(json_data, indent=2, sort_keys=True)
            print ("JSON ::")
            print (json_string)
        if response.content_type == defines.Content_types["application/link-format"]:
            #json_data = cbor.loads(response.payload)
            #json_string = json.dumps(json_data, indent=2, sort_keys=True)
            #print ("JSON ::")
            print (response.payload.decode())
            print ("\n\n")
            
            
        if response.content_type == defines.Content_types["application/vnd.ocf+cbor"]:
            json_data = cbor.loads(response.payload)
            json_string = json.dumps(json_data, indent=2, sort_keys=True)
            print ("JSON ::")
            print (json_string)
        client.stop()
    elif op == "GETNONE":
        if path is None:
            print("Path cannot be empty for a GET-None request")
            usage()
            sys.exit(2)
        response = client.get_non(path, None, None, **ct)
        print((response.pretty_print()))
        if response.content_type == defines.Content_types["application/json"]:
            json_data = json.loads(response.payload)
            json_string = json.dumps(json_data, indent=2, sort_keys=True)
            print ("JSON ::")
            print (json_string)
        if response.content_type == defines.Content_types["application/cbor"]:
            json_data = cbor.loads(response.payload)
            json_string = json.dumps(json_data, indent=2, sort_keys=True)
            print ("JSON ::")
            print (json_string)
        if response.content_type == defines.Content_types["application/vnd.ocf+cbor"]:
            json_data = cbor.loads(response.payload)
            json_string = json.dumps(json_data, indent=2, sort_keys=True)
            print ("JSON ::")
            print (json_string)
        client.stop()
    elif op == "OBSERVE":
        if path is None:
            print("Path cannot be empty for a GET request")
            usage()
            sys.exit(2)
        client.observe(path, client_callback_observe)
        
    elif op == "DELETE":
        if path is None:
            print("Path cannot be empty for a DELETE request")
            usage()
            sys.exit(2)
        response = client.delete(path)
        print((response.pretty_print()))
        client.stop()
    elif op == "POST":
        if path is None:
            print("Path cannot be empty for a POST request")
            usage()
            sys.exit(2)
        if payload is None:
            print("Payload cannot be empty for a POST request")
            usage()
            sys.exit(2)
        print ( "payload for POST (ascii):", payload )
        print (ct['accept'] )
        if ct['accept'] == str(defines.Content_types["application/cbor"]):
            json_data = json.loads(payload)
            cbor_data = cbor.dumps(json_data)
            payload = bytes(cbor_data)
        if ct['accept'] == str(defines.Content_types["application/vnd.ocf+cbor"]):
            json_data = json.loads(payload)
            cbor_data = cbor.loads(json_data)
            payload = cbor_data
            
        response = client.post(path, payload, None, None, **ct)
        
        print((response.pretty_print()))
        if response.content_type == defines.Content_types["application/cbor"]:
            json_data = cbor.loads(response.payload)
            json_string = json.dumps(json_data, indent=2, sort_keys=True)
            print (json_string)
        if response.content_type == defines.Content_types["application/vnd.ocf+cbor"]:
            json_data = cbor.loads(response.payload)
            json_string = json.dumps(json_data, indent=2, sort_keys=True)
            print (json_string)
        client.stop()
    elif op == "PUT":
        if path is None:
            print("Path cannot be empty for a PUT request")
            usage()
            sys.exit(2)
        if payload is None:
            print("Payload cannot be empty for a PUT request")
            usage()
            sys.exit(2)
        response = client.put(path, payload)
        print((response.pretty_print()))
        client.stop()
    elif op == "DISCOVER":
        #response = client.discover( path, client_callback, None, **ct)
        response = client.discover( path, None, None, **ct)
        if response is not None:
            print(response.pretty_print())
            if response.content_type == defines.Content_types["application/cbor"]:
                json_data = cbor.loads(response.payload)
                json_string = json.dumps(json_data, indent=2, sort_keys=True)
                print (json_string)
            if response.content_type == defines.Content_types["application/vnd.ocf+cbor"]:
                json_data = cbor.loads(response.payload)
                json_string = json.dumps(json_data, indent=2, sort_keys=True)
                print (json_string)
            if response.content_type == defines.Content_types["application/link-format"]:
                #json_data = cbor.loads(response.payload)
                #json_string = json.dumps(json_data, indent=2, sort_keys=True)
                print (response.payload.decode())
                # do_get(response.payload.decode(), client)
                client_callback_discovery(response)
        
        counter = 2
        try:
           while counter > 0:
              time.sleep(1)
              counter = counter - 1
           #client.stop()
        except KeyboardInterrupt:
           print("Client Shutdown")
           #client.stop()
           
        #execute_list()
        client.stop()
    else:
        print("Operation not recognized")
        usage()
        sys.exit(2)


if __name__ == '__main__':  # pragma: no cover
    main()

[((68, 16, 68, 38), 'cbor.loads', 'cbor.loads', ({(68, 27, 68, 37): 'sn.payload'}, {}), '(sn.payload)', False, 'import cbor\n'), ((719, 25, 719, 42), 'coapthon.utils.parse_uri', 'parse_uri', ({(719, 35, 719, 41): 'mypath'}, {}), '(mypath)', False, 'from coapthon.utils import parse_uri\n'), ((725, 16, 725, 49), 'coapthon.client.helperclient.HelperClient', 'HelperClient', (), '', False, 'from coapthon.client.helperclient import HelperClient\n'), ((743, 25, 743, 42), 'coapthon.utils.parse_uri', 'parse_uri', ({(743, 35, 743, 41): 'mypath'}, {}), '(mypath)', False, 'from coapthon.utils import parse_uri\n'), ((749, 16, 749, 49), 'coapthon.client.helperclient.HelperClient', 'HelperClient', (), '', False, 'from coapthon.client.helperclient import HelperClient\n'), ((750, 21, 750, 54), 'coapthon.client.helperclient.HelperClient', 'HelperClient', (), '', False, 'from coapthon.client.helperclient import HelperClient\n'), ((773, 25, 773, 42), 'coapthon.utils.parse_uri', 'parse_uri', ({(773, 35, 773, 41): 'mypath'}, {}), '(mypath)', False, 'from coapthon.utils import parse_uri\n'), ((779, 16, 779, 49), 'coapthon.client.helperclient.HelperClient', 'HelperClient', (), '', False, 'from coapthon.client.helperclient import HelperClient\n'), ((780, 21, 780, 54), 'coapthon.client.helperclient.HelperClient', 'HelperClient', (), '', False, 'from coapthon.client.helperclient import HelperClient\n'), ((807, 25, 807, 42), 'coapthon.utils.parse_uri', 'parse_uri', ({(807, 35, 807, 41): 'mypath'}, {}), '(mypath)', False, 'from coapthon.utils import parse_uri\n'), ((813, 16, 813, 49), 'coapthon.client.helperclient.HelperClient', 'HelperClient', (), '', False, 'from coapthon.client.helperclient import HelperClient\n'), ((879, 23, 879, 38), 'coapthon.utils.parse_uri', 'parse_uri', ({(879, 33, 879, 37): 'path'}, {}), '(path)', False, 'from coapthon.utils import parse_uri\n'), ((885, 13, 885, 46), 'coapthon.client.helperclient.HelperClient', 'HelperClient', (), '', False, 'from coapthon.client.helperclient import HelperClient\n'), ((721, 14, 721, 40), 'socket.gethostbyname', 'socket.gethostbyname', ({(721, 35, 721, 39): 'host'}, {}), '(host)', False, 'import socket\n'), ((745, 14, 745, 40), 'socket.gethostbyname', 'socket.gethostbyname', ({(745, 35, 745, 39): 'host'}, {}), '(host)', False, 'import socket\n'), ((775, 14, 775, 40), 'socket.gethostbyname', 'socket.gethostbyname', ({(775, 35, 775, 39): 'host'}, {}), '(host)', False, 'import socket\n'), ((784, 18, 784, 37), 'cbor.dumps', 'cbor.dumps', ({(784, 29, 784, 36): 'content'}, {}), '(content)', False, 'import cbor\n'), ((809, 14, 809, 40), 'socket.gethostbyname', 'socket.gethostbyname', ({(809, 35, 809, 39): 'host'}, {}), '(host)', False, 'import socket\n'), ((819, 18, 819, 37), 'cbor.dumps', 'cbor.dumps', ({(819, 29, 819, 36): 'content'}, {}), '(content)', False, 'import cbor\n'), ((837, 21, 838, 95), 'getopt.getopt', 'getopt.getopt', ({(837, 35, 837, 47): 'sys.argv[1:]', (837, 49, 837, 62): '"""ho:p:P:f:c:"""', (837, 64, 838, 94): "['help', 'operation=', 'path=', 'payload=', 'payload_file=', 'content-type']"}, {}), "(sys.argv[1:], 'ho:p:P:f:c:', ['help', 'operation=', 'path=',\n    'payload=', 'payload_file=', 'content-type'])", False, 'import getopt\n'), ((867, 8, 867, 19), 'sys.exit', 'sys.exit', ({(867, 17, 867, 18): '(2)'}, {}), '(2)', False, 'import sys\n'), ((872, 8, 872, 19), 'sys.exit', 'sys.exit', ({(872, 17, 872, 18): '(2)'}, {}), '(2)', False, 'import sys\n'), ((877, 8, 877, 19), 'sys.exit', 'sys.exit', ({(877, 17, 877, 18): '(2)'}, {}), '(2)', False, 'import sys\n'), ((881, 14, 881, 40), 'socket.gethostbyname', 'socket.gethostbyname', ({(881, 35, 881, 39): 'host'}, {}), '(host)', False, 'import socket\n'), ((843, 8, 843, 19), 'sys.exit', 'sys.exit', ({(843, 17, 843, 18): '(2)'}, {}), '(2)', False, 'import sys\n'), ((890, 12, 890, 23), 'sys.exit', 'sys.exit', ({(890, 21, 890, 22): '(2)'}, {}), '(2)', False, 'import sys\n'), ((894, 24, 894, 52), 'json.loads', 'json.loads', ({(894, 35, 894, 51): 'response.payload'}, {}), '(response.payload)', False, 'import json\n'), ((895, 26, 895, 73), 'json.dumps', 'json.dumps', (), '', False, 'import json\n'), ((899, 24, 899, 52), 'cbor.loads', 'cbor.loads', ({(899, 35, 899, 51): 'response.payload'}, {}), '(response.payload)', False, 'import cbor\n'), ((900, 26, 900, 73), 'json.dumps', 'json.dumps', (), '', False, 'import json\n'), ((912, 24, 912, 52), 'cbor.loads', 'cbor.loads', ({(912, 35, 912, 51): 'response.payload'}, {}), '(response.payload)', False, 'import cbor\n'), ((913, 26, 913, 73), 'json.dumps', 'json.dumps', (), '', False, 'import json\n'), ((921, 12, 921, 23), 'sys.exit', 'sys.exit', ({(921, 21, 921, 22): '(2)'}, {}), '(2)', False, 'import sys\n'), ((925, 24, 925, 52), 'json.loads', 'json.loads', ({(925, 35, 925, 51): 'response.payload'}, {}), '(response.payload)', False, 'import json\n'), ((926, 26, 926, 73), 'json.dumps', 'json.dumps', (), '', False, 'import json\n'), ((930, 24, 930, 52), 'cbor.loads', 'cbor.loads', ({(930, 35, 930, 51): 'response.payload'}, {}), '(response.payload)', False, 'import cbor\n'), ((931, 26, 931, 73), 'json.dumps', 'json.dumps', (), '', False, 'import json\n'), ((935, 24, 935, 52), 'cbor.loads', 'cbor.loads', ({(935, 35, 935, 51): 'response.payload'}, {}), '(response.payload)', False, 'import cbor\n'), ((936, 26, 936, 73), 'json.dumps', 'json.dumps', (), '', False, 'import json\n'), ((632, 28, 632, 56), 'cbor.loads', 'cbor.loads', ({(632, 39, 632, 55): 'response.payload'}, {}), '(response.payload)', False, 'import cbor\n'), ((633, 30, 633, 77), 'json.dumps', 'json.dumps', (), '', False, 'import json\n'), ((639, 28, 639, 49), 'cbor.loads', 'cbor.loads', ({(639, 39, 639, 48): 'checkdata'}, {}), '(checkdata)', False, 'import cbor\n'), ((640, 30, 640, 78), 'json.dumps', 'json.dumps', (), '', False, 'import json\n'), ((661, 26, 661, 73), 'json.dumps', 'json.dumps', (), '', False, 'import json\n'), ((944, 12, 944, 23), 'sys.exit', 'sys.exit', ({(944, 21, 944, 22): '(2)'}, {}), '(2)', False, 'import sys\n'), ((656, 28, 656, 56), 'cbor.loads', 'cbor.loads', ({(656, 39, 656, 55): 'response.payload'}, {}), '(response.payload)', False, 'import cbor\n'), ((951, 12, 951, 23), 'sys.exit', 'sys.exit', ({(951, 21, 951, 22): '(2)'}, {}), '(2)', False, 'import sys\n'), ((660, 16, 660, 37), 'traceback.print_exc', 'traceback.print_exc', ({}, {}), '()', False, 'import traceback\n'), ((959, 12, 959, 23), 'sys.exit', 'sys.exit', ({(959, 21, 959, 22): '(2)'}, {}), '(2)', False, 'import sys\n'), ((963, 12, 963, 23), 'sys.exit', 'sys.exit', ({(963, 21, 963, 22): '(2)'}, {}), '(2)', False, 'import sys\n'), ((967, 24, 967, 43), 'json.loads', 'json.loads', ({(967, 35, 967, 42): 'payload'}, {}), '(payload)', False, 'import json\n'), ((968, 24, 968, 45), 'cbor.dumps', 'cbor.dumps', ({(968, 35, 968, 44): 'json_data'}, {}), '(json_data)', False, 'import cbor\n'), ((971, 24, 971, 43), 'json.loads', 'json.loads', ({(971, 35, 971, 42): 'payload'}, {}), '(payload)', False, 'import json\n'), ((972, 24, 972, 45), 'cbor.loads', 'cbor.loads', ({(972, 35, 972, 44): 'json_data'}, {}), '(json_data)', False, 'import cbor\n'), ((979, 24, 979, 52), 'cbor.loads', 'cbor.loads', ({(979, 35, 979, 51): 'response.payload'}, {}), '(response.payload)', False, 'import cbor\n'), ((980, 26, 980, 73), 'json.dumps', 'json.dumps', (), '', False, 'import json\n'), ((983, 24, 983, 52), 'cbor.loads', 'cbor.loads', ({(983, 35, 983, 51): 'response.payload'}, {}), '(response.payload)', False, 'import cbor\n'), ((984, 26, 984, 73), 'json.dumps', 'json.dumps', (), '', False, 'import json\n'), ((859, 12, 859, 22), 'sys.exit', 'sys.exit', ({}, {}), '()', False, 'import sys\n'), ((862, 12, 862, 23), 'sys.exit', 'sys.exit', ({(862, 21, 862, 22): '(2)'}, {}), '(2)', False, 'import sys\n'), ((991, 12, 991, 23), 'sys.exit', 'sys.exit', ({(991, 21, 991, 22): '(2)'}, {}), '(2)', False, 'import sys\n'), ((995, 12, 995, 23), 'sys.exit', 'sys.exit', ({(995, 21, 995, 22): '(2)'}, {}), '(2)', False, 'import sys\n'), ((1034, 8, 1034, 19), 'sys.exit', 'sys.exit', ({(1034, 17, 1034, 18): '(2)'}, {}), '(2)', False, 'import sys\n'), ((1005, 28, 1005, 56), 'cbor.loads', 'cbor.loads', ({(1005, 39, 1005, 55): 'response.payload'}, {}), '(response.payload)', False, 'import cbor\n'), ((1006, 30, 1006, 77), 'json.dumps', 'json.dumps', (), '', False, 'import json\n'), ((1009, 28, 1009, 56), 'cbor.loads', 'cbor.loads', ({(1009, 39, 1009, 55): 'response.payload'}, {}), '(response.payload)', False, 'import cbor\n'), ((1010, 30, 1010, 77), 'json.dumps', 'json.dumps', (), '', False, 'import json\n'), ((1022, 14, 1022, 27), 'time.sleep', 'time.sleep', ({(1022, 25, 1022, 26): '(1)'}, {}), '(1)', False, 'import time\n')]