Example #1
0
def process_datagram(cli, msg):
    src_id = int(msg[7:10], 16)
    s = cli.sock
    #for now we assume a one frame datagram
    dest_node_alias = int(msg[4:7], 16)
    dest_node, cli_dest = buses.find_managed_node(dest_node_alias)
    if dest_node is None or not dest_node.permitted:  #not for us or the node is not ready yet
        debug("Frame is not for us or node is not ready!!")
        #forward to all other OLCB clients
        OLCB_serv.transfer(msg.encode('utf-8'), cli)
        return
    src_node = find_node(src_id)

    if dest_node.current_write is not None:
        #if there is a write in progress then this datagram is part of it
        if memory_write(s, dest_node, src_node, msg):
            cli_dest.bus.nodes_db.synced = False

    elif msg[11:15] == "2043":  #read command for CDI
        address = int(msg[15:23], 16)
        debug("read command, address=", int(msg[15:23], 16))
        s.send((":X19A28" + hexp(dest_node.aliasID, 3) + "N0" +
                hexp(src_id, 3) + ";").encode('utf-8'))
        debug("datagram received ok sent --->",
              (":X19A28" + hexp(dest_node.aliasID, 3) + "N0" +
               hexp(src_id, 3) + ";").encode("utf-8"))
        send_CDI(s, dest_node, src_node, address, int(msg[23:25], 16))

    elif msg[11:14] == "200" or msg[11:14] == "204":  #read/write command
        s.send((":X19A28" + hexp(dest_node.aliasID, 3) + "N0" +
                hexp(src_id, 3) + ";").encode('utf-8'))
        debug("datagram received ok sent --->",
              (":X19A28" + hexp(dest_node.aliasID, 3) + "N0" +
               hexp(src_id, 3) + ";").encode("utf-8"))
        if msg[13] == "4":
            address = int(msg[15:23], 16)
            memory_read(s, dest_node, src_node, address, msg)
        elif msg[13] == "0":
            if memory_write(s, dest_node, src_node, msg):
                cli_dest.bus.nodes_db.synced = False
        elif msg[11:13] == "20":
            #other commands than read/write
            if msg[13:15] == "A8":
                #CDI update complete, we do not have to reply so we dont for now
                debug("Update complete received from node ", src_node.ID)
            elif msg[13:15] == "80":
                #Get configurations options
                dgram = Datagram_content.build_get_config_opt_reply(
                    dest_node, src_node)
                s.send(dgram.to_gridconnect())
                debug("---> S: config opt reply=", dgram.to_gridconnect())
Example #2
0
def check_alias(alias):
    """
    Checks if the alias is used by one of our nodes
    if yes transition the node to inhibited state, send AMR frame
    and reset alias negotiation for the node
    """

    node, node_cli = buses.find_managed_node(alias)
    if node_cli is None:
        return None
    node.permitted = False
    #reset the alias negotiation
    alias_neg = node.create_alias_negotiation()
    #loop while we find an unused alias
    while (alias_neg.aliasID in reserved_aliases) or (get_alias_neg_from_alias(
            alias_neg.aliasID) is not None):
        alias_neg = node.create_alias_negotiation()
    #register to the bus alias neg list
    node_cli[1].bus.nodes_in_alias_negotiation.append((node, alias_neg))
    #also add it to the list of aliases negotiation
    list_alias_neg.append(alias_neg)
    #send AMR to all openlcb nodes
    OLCB_serv.send(Frame.build_AMR(node))
Example #3
0
def global_frame(cli, msg):
    first_b = int(msg[2:4], 16)
    var_field = int(msg[4:7], 16)
    src_id = int(msg[7:10], 16)
    s = cli.sock

    if var_field == 0x490:
        #forward to all other clients
        OLCB_serv.transfer(msg.encode('utf-8'), cli)
        for b in buses.Bus_manager.buses:
            for c in b.clients:
                for n in c.managed_nodes:
                    if n.permitted:
                        OLCB_serv.transfer(
                            (":X19170" + hexp(n.aliasID, 3) + "N" +
                             hexp(n.ID, 12) + ";").encode('utf-8'))
                        debug("Sent---> :X19170" + hexp(n.aliasID, 3) + "N" +
                              hexp(n.ID, 12) + ";")

    elif var_field == 0x828:  #Protocol Support Inquiry
        dest_node_alias = int(msg[12:15], 16)
        dest_node, cli_dest = buses.find_managed_node(dest_node_alias)

        if dest_node is not None:
            #FIXME: set correct bits
            s.send((":X19668" + hexp(dest_node.aliasID, 3) + "N0" +
                    hexp(src_id, 3) + hexp(SPSP | SNIP | CDIP, 6) +
                    "000000;").encode("utf-8"))
            debug("sent--->:X19668" + hexp(dest_node.aliasID, 3) + "N0" +
                  hexp(src_id, 3) + hexp(SPSP | SNIP | CDIP, 6) + "000000;")

    elif var_field == 0xDE8:  #Simple Node Information Request
        dest_node_alias = int(msg[12:15], 16)
        dest_node, cli_dest = buses.find_managed_node(dest_node_alias)
        if dest_node is not None:
            debug("sent SNIR Reply")
            #s.send((":X19A08"+hexp(gw_add.aliasID,3)+"N1"+hexp(src_id,3)+"04;").encode("utf-8"))#SNIR header
            #print(":X19A08"+hexp(gw_add.aliasID,3)+"N1"+hexp(src_id,3)+"04;")
            #FIXME:
            src_node = find_node(src_id)
            send_fields(s, dest_node, 0xA08, mfg_name_hw_sw_version, src_node)

    elif var_field == 0x5B4:  #PCER (event)
        #transfer to all other openlcb clients
        OLCB_serv.transfer(msg.encode('utf-8'), cli)
        ev_id = bytes([int(msg[11 + i * 2:13 + i * 2], 16) for i in range(8)])
        debug("received event:", ev_id)
        for b in buses.Bus_manager.buses:
            path = b.path_to_nodes_files
            if path is not None:
                if path != "":
                    path += "/"
                path += str(n.ID) + ".outputs"
            for c in b.clients:
                for n in c.managed_nodes:
                    if n.permitted:
                        n.consume_event(Event(ev_id), path)
    elif var_field == 0x914 or var_field == 0x8F4:  #identify producer/consumer
        #transfer to all other openlcb clients
        OLCB_serv.transfer(msg.encode('utf-8'), cli)
        process_id_prod_consumer(cli, msg)
    elif var_field == 0x970 or var_field == 0x968:  #identify events
        #transfer to all other openlcb clients
        OLCB_serv.transfer(msg.encode('utf-8'), cli)
        identify_events(msg, cli)
    elif var_field == 0x4C4 or var_field == 0x4C5 or var_field == 0x4C7:  #consumer identified
        OLCB_serv.transfer(msg.encode('utf-8'), cli)
        consum_identified(msg, cli)
    elif var_field == 0x544 or var_field == 0x545 or var_field == 0x547:  #producer identified
        OLCB_serv.transfer(msg.encode('utf-8'), cli)
        produc_identified(msg, cli)
Example #4
0
def can_control_frame(cli, msg):
    #transfer to all other openlcb clients
    OLCB_serv.transfer(msg.encode('utf-8'), cli)
    first_b = int(msg[2:4], 16)
    var_field = int(msg[4:7], 16)
    src_id = int(msg[7:10], 16)
    data_needed = False
    if first_b & 0x7 >= 4 and first_b & 0x7 <= 7:
        debug("CID Frame n°", first_b & 0x7, " * ", hex(var_field))
        #full_ID = var_field << 12*((first_b&0x7) -4)
        new = False
        if first_b & 0x7 == 7:
            if get_alias_neg_from_alias(src_id) is not None:
                debug("Alias collision")
                #fixme: what to do here??
                return
            alias_neg = Alias_negotiation(src_id)
            new = True
        else:
            alias_neg = get_alias_neg_from_alias(src_id)
            if alias_neg is None:
                debug("CID frame with no previous alias negotiation!")
                alias_neg = Alias_negotiation(src_id, 0, 8 - (first_b & 0x07))
                new = True
        alias_neg.next_step(var_field)
        if new:
            list_alias_neg.append(alias_neg)
        #if we have a node in permitted state we send an AMD frame
        node_cli = buses.find_managed_node(src_id)
        if node_cli is not None:
            OLCB_serv.send(Frame.build_AMD(node_cli[0]))

    elif first_b & 0x7 == 0:
        if var_field == 0x700:
            debug("RID Frame * full ID=")
            neg = get_alias_neg_from_alias(src_id)
            if neg is None:
                #no CID before that create the alias_negotiation
                neg = Alias_negotiation(src_id, 0, 4)
                list_alias_neg.append(neg)
            reserve_aliasID(src_id)
            #create node but not in permitted state
            new_node(Node(neg.fullID, False, neg.aliasID))
            check_alias(src_id)

        elif var_field == 0x701:
            debug("AMD Frame")
            check_alias(src_id)
            if src_id in reserved_aliases:
                node = find_node(src_id)
                if node is None:
                    debug("AMD frame received (alias=", src_id,
                          ") but node does not exist!")
                else:
                    #change to permitted state
                    node.permitted = True
            else:
                debug("AMD frame received (alias=", src_id,
                      ") but not reserved before!")
                #create alias, reserve it
                neg = Alias_negotiation(src_id, 0, 4)
                list_alias_neg.append(neg)
                reserve_aliasID(src_id)
                #create node in permitted state
                new_node(Node(int(msg[11:23], 16), True, src_id))
            data_needed = True  #we could check the fullID

        elif var_field == 0x702:
            debug("AME Frame")
            for b in buses.Bus_manager.buses:
                for c in b.clients:
                    for n in c.managed_nodes:
                        if n.permitted:
                            f = Frame.build_AMD(n)
                            OLCB_serv.send(f)
                            debug("sent---->:", f.to_gridconnect())
                            debug("Sent---> :X19170" + hexp(n.aliasID, 3) +
                                  "N" + hexp(n.ID, 12) + ";")
        elif var_field == 0x703:
            #FIXME!
            debug("AMR Frame")
            data_nedded = True
        elif var_field >= 0x710 and var_field <= 0x713:
            debug("Unknown Frame")
    debug(hexp(src_id, 3))
    if data_needed and not data_present:
        debug("Data needed but none is present!")
        return