Ejemplo n.º 1
0
tag_create_function find_tag_create_func(attr attributes)
{
    int i = 0;
    const char *protocol = attr_get_str(attributes, "protocol", NULL);
    const char *make = attr_get_str(attributes, "make", attr_get_str(attributes, "manufacturer", NULL));
    const char *family = attr_get_str(attributes, "family", NULL);
    const char *model = attr_get_str(attributes, "model", NULL);
    int num_entries = (sizeof(tag_type_map)/sizeof(tag_type_map[0]));

    /* if protocol is set, then use it to match. */
    if(protocol && str_length(protocol) > 0) {
        for(i=0; i < num_entries; i++) {
            if(tag_type_map[i].protocol && str_cmp(tag_type_map[i].protocol, protocol) == 0) {
                pdebug(DEBUG_INFO,"Matched protocol=%s", protocol);
                return tag_type_map[i].tag_constructor;
            }
        }
    } else {
        /* match make/family/model */
        for(i=0; i < num_entries; i++) {
            if(tag_type_map[i].make && make && str_cmp_i(tag_type_map[i].make, make) == 0) {
                pdebug(DEBUG_INFO,"Matched make=%s",make);
                if(tag_type_map[i].family) {
                    if(family && str_cmp_i(tag_type_map[i].family, family) == 0) {
                        pdebug(DEBUG_INFO, "Matched make=%s family=%s", make, family);
                        if(tag_type_map[i].model) {
                            if(model && str_cmp_i(tag_type_map[i].model, model) == 0) {
                                pdebug(DEBUG_INFO, "Matched make=%s family=%s model=%s", make, family, model);
                                return tag_type_map[i].tag_constructor;
                            }
                        } else {
                            /* matches until a NULL */
                            pdebug(DEBUG_INFO, "Matched make=%s family=%s model=NULL", make, family);
                            return tag_type_map[i].tag_constructor;
                        }
                    }
                } else {
                    /* matched until a NULL, so we matched */
                    pdebug(DEBUG_INFO, "Matched make=%s family=NULL model=NULL", make);
                    return tag_type_map[i].tag_constructor;
                }
            }
        }
    }

    /* no match */
    return NULL;
}
Ejemplo n.º 2
0
extern float attr_get_float(attr attrs, const char *name, float def)
{
	float res;
	int rc;

	const char *str_val = attr_get_str(attrs,name, NULL);

	if(!str_val) {
		return def;
	}

	rc = str_to_float(str_val, &res);

	if(rc) {
		/* format error? */
		return def;
	} else {
		return res;
	}
}
Ejemplo n.º 3
0
plc_tag ab_tag_create(attr attribs)
{
    ab_tag_p tag = AB_TAG_NULL;
    const char *path;
	int rc;
	int debug = attr_get_int(attribs,"debug",0);

    pdebug(debug,"Starting.");


    /*
     * allocate memory for the new tag.  Do this first so that
     * we have a vehicle for returning status.
     */

    tag = (ab_tag_p)mem_alloc(sizeof(struct ab_tag_t));

    if(!tag) {
    	pdebug(debug,"Unable to allocate memory for AB EIP tag!");
    	return PLC_TAG_NULL;
    }

    /* store the debug status */
    tag->debug = debug;

    /*
     * check the CPU type.
     *
     * This determines the protocol type.
     */
    if(check_cpu(tag, attribs) != PLCTAG_STATUS_OK) {
        tag->status = PLCTAG_ERR_BAD_DEVICE;
        return (plc_tag)tag;
    }

    /* AB PLCs are little endian. */
    tag->endian = PLCTAG_DATA_LITTLE_ENDIAN;

    /* allocate memory for the data */
    tag->elem_count = attr_get_int(attribs,"elem_count",1);
    tag->elem_size = attr_get_int(attribs,"elem_size",0);
    tag->size = (tag->elem_count) * (tag->elem_size);

    if(tag->size == 0) {
    	/* failure! Need data_size! */
    	tag->status = PLCTAG_ERR_BAD_PARAM;
    	return (plc_tag)tag;
    }

    tag->data = (uint8_t*)mem_alloc(tag->size);

    if(tag->data == NULL) {
    	tag->status = PLCTAG_ERR_NO_MEM;
    	return (plc_tag)tag;
    }

    /* get the connection path, punt if there is not one and we have a Logix-class PLC. */
    path = attr_get_str(attribs,"path",NULL);

    if(path == NULL && tag->protocol_type == AB_PROTOCOL_LGX) {
    	tag->status = PLCTAG_ERR_BAD_PARAM;
    	return (plc_tag)tag;
    }

    /* make sure the global mutex is set up */
    rc = check_mutex(tag->debug);
    if(rc != PLCTAG_STATUS_OK) {
    	tag->status = rc;
    	return (plc_tag)tag;
    }

    tag->first_read = 1;

	/*
	 * now we start the part that might conflict with other threads.
	 *
	 * The rest of this is inside a locked block.
	 */
	pdebug(debug,"Locking mutex");
	critical_block(io_thread_mutex) {
		/*
		 * set up tag vtable.  This is protocol specific
		 */
		tag->vtable = set_tag_vtable(tag);

		if(!tag->vtable) {
			pdebug(debug,"Unable to set tag vtable!");
			tag->status = PLCTAG_ERR_BAD_PARAM;
			break;
		}

		/*
		 * Check the request IO handler thread.
		 */
		if(!io_handler_thread) {
			rc = thread_create((thread_p*)&io_handler_thread,request_handler_func, 32*1024, NULL);
			if(rc != PLCTAG_STATUS_OK) {
				pdebug(debug,"Unable to create request handler thread!");
				tag->status = rc;
				break;
			}
		}

		/*
		 * Find or create a session.
		 */
		if(find_or_create_session(tag, attribs) != PLCTAG_STATUS_OK) {
			pdebug(debug,"Unable to create session!");
			tag->status = PLCTAG_ERR_BAD_GATEWAY;
			break;
		}

		/*
		 * parse the link path into the tag.  Note that it must
		 * pad the byte string to a multiple of 16-bit words. The function
		 * also adds the protocol/PLC specific routing information to the
		 * links specified.  This fills in fields in the connection about
		 * any DH+ special data.
		 * 
		 * Skip this if we don't have a path.
		 */
		if(path && cip_encode_path(tag,path) != PLCTAG_STATUS_OK) {
			pdebug(debug,"Unable to convert links strings to binary path!");
			tag->status = PLCTAG_ERR_BAD_PARAM;
			break;
		}


		/*
		 * check the tag name, this is protocol specific.
		 */

		if(check_tag_name(tag, attr_get_str(attribs,"name","NONE")) != PLCTAG_STATUS_OK) {
			pdebug(debug,"Bad tag name!");
			tag->status = PLCTAG_ERR_BAD_PARAM;
			break;
		}

		/*
		 * add the tag to the session's list.
		 */
		if(session_add_tag_unsafe(tag, tag->session) != PLCTAG_STATUS_OK) {
			pdebug(debug,"unable to add new tag to connection!");

			tag->status = PLCTAG_ERR_CREATE;
			break;
		}
    }

    pdebug(debug,"Done.");

    return (plc_tag)tag;
}