예제 #1
0
int admin_deleteAccount() {
	char buffer[MAX_BUFFER_LEN];
	accountnr_t number;
	cls();
	printf("Eliminar conta\n"
			"----------------\n");
	// Number:
	do {
		printf("Numero de conta: ");
		gets(buffer);
		number = atoi(buffer);
	} while (strlen(buffer) > 7 || strlen(buffer) == 0 || number < 1
			|| number > 9999999 || !isInteger(buffer));

	struct Request r;
	char *msg = malloc(sizeof(char) * 10);
	char* wrStr = malloc(sizeof(char) * 128);
	sprintf(wrStr, "DELETE ACCOUNT %i\n", number);
	request_create(&r, getpid(), "ADMIN", wrStr);
	request_writeFIFO("/tmp/requests", &r, NULL);
	request_waitFIFO(fifoname, NULL, msg);
	printf("%s\n", msg);
	getchar();

	if (strcmp(msg, "OK") == 0)
		return 1;
	else
		return 0;

}
예제 #2
0
파일: check_redis.c 프로젝트: huayl/pelikan
/*
 * utilities
 */
static void
test_setup(void)
{
    req = request_create();
    rsp = response_create();
    buf = buf_create();
}
예제 #3
0
void admin_listAccounts() {
	cls();
	printf("Listar contas\n"
			"----------------\n");

	struct Request r;
	//TODO OPTIMIZE THIS MALLOC
	char msg[500];
	char* wrStr = malloc(sizeof(char) * 50);
	sprintf(wrStr, "LIST");
	request_create(&r, getpid(), "ADMIN", wrStr);
	request_writeFIFO("/tmp/requests", &r, NULL);
	request_waitFIFO(fifoname, NULL, msg);

	if (strcmp(msg, "FAIL") == 0)
		printf("Não existem contas!\n");
	else {
		int i;
		for (i = 0; i < sizeof(msg); i++) {
			if (msg[i] == '\0')
				break;
			if (msg[i] == '>')
				msg[i] = '\n';
			if (msg[i] == '|')
				msg[i] = ' ';
		}
		printf("%s", msg);
	}
	getchar();
}
예제 #4
0
/*
 * Core function to create a mailbox.
 */
static int
ifcore_create(lua_State *lua)
{
	const char *s, *u, *p;
	int r;

	if (lua_gettop(lua) != 2)
		luaL_error(lua, "wrong number of arguments");

	luaL_checktype(lua, 1, LUA_TTABLE);
	luaL_checktype(lua, 2, LUA_TSTRING);

	lua_pushvalue(lua, 1);
	if (!(s = get_table_string("server")))
		luaL_error(lua, "no mail server specified");
	if (!(u = get_table_string("username")))
		luaL_error(lua, "no username specified");
	p = DISCOVER_PORT(get_table_string("port"), get_table_string("ssl"));
	lua_pop(lua, 1);

	r = request_create(s, p, u, lua_tostring(lua, 2));

	lua_pop(lua, 2);

	lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));

	return 1;
}
예제 #5
0
HttpClient *httpclient_create(char *host, char *port){
	HttpClient *httpClient;
    //request_init();

    httpClient = (HttpClient *)malloc(sizeof(HttpClient));
    if(httpClient == NULL){
        printf("failed to create httpClient instance\n");
        return  NULL;
    }
    httpClient->request = request_create(host, port);;
    httpClient->response = response_create();

    return  httpClient;
}
예제 #6
0
int admin_shutdownServer() {
	cls();
	printf("Encerrar Servidor\n"
			"----------------\n");
	struct Request r;
	char* msg = malloc(sizeof(char) * 10);
	request_create(&r, getpid(), "ADMIN", "SHUTDOWN");
	request_writeFIFO("/tmp/requests", &r, NULL);
	request_waitFIFO(fifoname, NULL, msg);
	printf("%s\n", msg);
	if (strcmp(msg, "OK") == 0)
		return 1;
	else
		return 0;
}
예제 #7
0
파일: core.c 프로젝트: divdot/imapfilter
/*
 * Core function to create a mailbox.
 */
static int
ifcore_create(lua_State *lua)
{
	int r;

	if (lua_gettop(lua) != 2)
		luaL_error(lua, "wrong number of arguments");
	luaL_checktype(lua, 1, LUA_TLIGHTUSERDATA);
	luaL_checktype(lua, 2, LUA_TSTRING);

	while ((r = request_create((session *)(lua_topointer(lua, 1)),
	    lua_tostring(lua, 2))) == STATUS_NONE);

	lua_pop(lua, 2);

	if (r == -1)
		return 0;

	lua_pushboolean(lua, (r == STATUS_OK));

	return 1;
}
예제 #8
0
int eip_pccc_tag_read_start(ab_tag_p tag)
{
    int rc = PLCTAG_STATUS_OK;
    ab_request_p req;
    uint16_t conn_seq_id = (uint16_t)(session_get_new_seq_id(tag->session));;
    int overhead;
    int data_per_packet;
    pccc_req *pccc;
    uint8_t *data;
    uint8_t *embed_start;
    int debug = tag->debug;

    pdebug(debug,"Starting");

    /* how many packets will we need? How much overhead? */
    overhead = sizeof(pccc_resp) + 4 + tag->encoded_name_size; /* MAGIC 4 = fudge */

    data_per_packet = MAX_PCCC_PACKET_SIZE - overhead;

	if(data_per_packet <= 0) {
		pdebug(debug,"Unable to send request.  Packet overhead, %d bytes, is too large for packet, %d bytes!", overhead, MAX_EIP_PACKET_SIZE);
		tag->status = PLCTAG_ERR_TOO_LONG;
		return tag->status;
	}

	if(data_per_packet < tag->size) {
		pdebug(debug,"PCCC requests cannot be fragmented.  Too much data requested.");
		tag->status = PLCTAG_ERR_TOO_LONG;
		return tag->status;
	}

	if(!tag->reqs) {
		tag->reqs = (ab_request_p*)mem_alloc(1 * sizeof(ab_request_p));
		tag->max_requests = 1;
		tag->num_read_requests = 1;
		tag->num_write_requests = 1;

		if(!tag->reqs) {
			pdebug(debug,"Unable to get memory for request array!");
			tag->status = PLCTAG_ERR_NO_MEM;
			return tag->status;
		}
	}

	/* get a request buffer */
	rc = request_create(&req);

	if(rc != PLCTAG_STATUS_OK) {
		pdebug(debug,"Unable to get new request.  rc=%d",rc);
		tag->status = rc;
		return rc;
	}

	req->debug = tag->debug;

	/* point the struct pointers to the buffer*/
	pccc = (pccc_req*)(req->data);

	/* set up the embedded PCCC packet */
	embed_start = (uint8_t*)(&pccc->service_code);

	/* Command Routing */
	pccc->service_code = AB_EIP_CMD_PCCC_EXECUTE;  /* ALWAYS 0x4B, Execute PCCC */
	pccc->req_path_size = 2;   /* ALWAYS 2, size in words of path, next field */
	pccc->req_path[0] = 0x20;  /* class */
	pccc->req_path[1] = 0x67;  /* PCCC Execute */
	pccc->req_path[2] = 0x24;  /* instance */
	pccc->req_path[3] = 0x01;  /* instance 1 */

	/* PCCC ID */
	pccc->request_id_size = 7;  /* ALWAYS 7 */
	pccc->vendor_id = h2le16(AB_EIP_VENDOR_ID);             /* Our CIP Vendor */
	pccc->vendor_serial_number = h2le32(AB_EIP_VENDOR_SN);      /* our unique serial number */

	/* fill in the PCCC command */
	pccc->pccc_command = AB_EIP_PCCC_TYPED_CMD;
	pccc->pccc_status = 0;  /* STS 0 in request */
	pccc->pccc_seq_num = h2le16(conn_seq_id); /* FIXME - get sequence ID from session? */
	pccc->pccc_function = AB_EIP_PCCC_TYPED_READ_FUNC;
	pccc->pccc_transfer_size = h2le16(tag->elem_count); /* This is not in the docs, but it is in the data. */

	/* point to the end of the struct */
	data = ((uint8_t *)pccc) + sizeof(pccc_req);
	
	/* copy LAA tag name into the request */
	mem_copy(data,tag->encoded_name,tag->encoded_name_size);
	data += tag->encoded_name_size;
	
	/* we need the count twice? */
	*((uint16_t*)data) = h2le16(tag->elem_count); /* FIXME - bytes or INTs? */
	data += sizeof(uint16_t);
	
	/*
	 * after the embedded packet, we need to tell the message router
	 * how to get to the target device.
	 */

	/* encap fields */
	pccc->encap_command = h2le16(AB_EIP_READ_RR_DATA);    /* ALWAYS 0x0070 Unconnected Send*/

	/* router timeout */
	pccc->router_timeout = h2le16(1);                 /* one second timeout, enough? */

	/* Common Packet Format fields for unconnected send. */
	pccc->cpf_item_count 		= h2le16(2);				/* ALWAYS 2 */
	pccc->cpf_nai_item_type 	= h2le16(AB_EIP_ITEM_NAI);  /* ALWAYS 0 */
	pccc->cpf_nai_item_length 	= h2le16(0);   				/* ALWAYS 0 */
	pccc->cpf_udi_item_type		= h2le16(AB_EIP_ITEM_UDI);  /* ALWAYS 0x00B2 - Unconnected Data Item */
	pccc->cpf_udi_item_length	= h2le16(data - embed_start);  /* REQ: fill in with length of remaining data. */

	/* set the size of the request */
	req->request_size = data - (req->data);

	/* mark it as ready to send */
	req->send_request = 1;

	/* add the request to the session's list. */
	rc = request_add(tag->session, req);

	if(rc != PLCTAG_STATUS_OK) {
		pdebug(debug,"Unable to lock add request to session! rc=%d",rc);
		request_destroy(&req);
		tag->status = rc;
		return rc;
	}

	/* save the request for later */
	tag->reqs[0] = req;
	req = NULL;

    tag->read_in_progress = 1;

    tag->status = PLCTAG_STATUS_PENDING;

    return PLCTAG_STATUS_PENDING;
}
예제 #9
0
int eip_pccc_tag_write_start(ab_tag_p tag)
{
	int rc = PLCTAG_STATUS_OK;
    pccc_req *pccc;
    uint8_t *data;
    uint8_t element_def[16];
    int element_def_size;
    uint8_t array_def[16];
    int array_def_size;
    int pccc_data_type;
    uint16_t conn_seq_id = (uint16_t)(session_get_new_seq_id(tag->session));;
    ab_request_p req = NULL;
    int debug = tag->debug;
	uint8_t *embed_start;
	int overhead, data_per_packet;

    pdebug(debug,"Starting.");
	
	/* how many packets will we need? How much overhead? */
    overhead = sizeof(pccc_resp) + 4 + tag->encoded_name_size; /* MAGIC 4 = fudge */

    data_per_packet = MAX_PCCC_PACKET_SIZE - overhead;

	if(data_per_packet <= 0) {
		pdebug(debug,"Unable to send request.  Packet overhead, %d bytes, is too large for packet, %d bytes!", overhead, MAX_EIP_PACKET_SIZE);
		tag->status = PLCTAG_ERR_TOO_LONG;
		return tag->status;
	}

	if(data_per_packet < tag->size) {
		pdebug(debug,"PCCC requests cannot be fragmented.  Too much data requested.");
		tag->status = PLCTAG_ERR_TOO_LONG;
		return tag->status;
	}

	
	/* set up the requests */
	if(!tag->reqs) {
		tag->reqs = (ab_request_p*)mem_alloc(1 * sizeof(ab_request_p));
		tag->max_requests = 1;
		tag->num_read_requests = 1;
		tag->num_write_requests = 1;

		if(!tag->reqs) {
			pdebug(debug,"Unable to get memory for request array!");
			tag->status = PLCTAG_ERR_NO_MEM;
			return tag->status;
		}
	}

    /* get a request buffer */
    rc = request_create(&req);

    if(rc != PLCTAG_STATUS_OK) {
    	pdebug(debug,"Unable to get new request.  rc=%d",rc);
    	tag->status = rc;
    	return rc;
    }

    req->debug = tag->debug;

    pccc = (pccc_req*)(req->data);

	/* set up the embedded PCCC packet */
	embed_start = (uint8_t*)(&pccc->service_code);

    /* point to the end of the struct */
    data = (req->data) + sizeof(pccc_req);

    /* copy laa into the request */
    mem_copy(data,tag->encoded_name,tag->encoded_name_size);
    data += tag->encoded_name_size;

    /* What type and size do we have? */
    if(tag->elem_size != 2 && tag->elem_size != 4) {
        pdebug(debug,"Unsupported data type size: %d",tag->elem_size);
    	request_destroy(&req);
    	tag->status = PLCTAG_ERR_NOT_ALLOWED;
        return PLCTAG_ERR_NOT_ALLOWED;
    }

    if(tag->elem_size == 4)
        pccc_data_type = AB_PCCC_DATA_REAL;
    else
        pccc_data_type = AB_PCCC_DATA_INT;

    /* generate the data type/data size fields, first the element part so that
     * we can get the size for the array part.
     */
    if(!(element_def_size = pccc_encode_dt_byte(element_def,sizeof(element_def),pccc_data_type,tag->elem_size))) {
        pdebug(debug,"Unable to encode PCCC request array element data type and size fields!");
    	request_destroy(&req);
    	tag->status = PLCTAG_ERR_ENCODE;
        return PLCTAG_ERR_ENCODE;
    }

    if(!(array_def_size = pccc_encode_dt_byte(array_def,sizeof(array_def),AB_PCCC_DATA_ARRAY,element_def_size + tag->size))) {
        pdebug(debug,"Unable to encode PCCC request data type and size fields!");
    	request_destroy(&req);
        tag->status = PLCTAG_ERR_ENCODE;
        return PLCTAG_ERR_ENCODE;
    }

    /* copy the array data first. */
    mem_copy(data,array_def,array_def_size);
    data += array_def_size;

    /* copy the element data */
    mem_copy(data,element_def,element_def_size);
    data += element_def_size;

    /* now copy the data to write */
    mem_copy(data,tag->data,tag->size);
    data += tag->size;

    /* now fill in the rest of the structure. */

    /* encap fields */
    pccc->encap_command = h2le16(AB_EIP_READ_RR_DATA);    /* ALWAYS 0x0070 Unconnected Send*/

    /* router timeout */
    pccc->router_timeout = h2le16(1);                 /* one second timeout, enough? */

 	/* Common Packet Format fields for unconnected send. */
	pccc->cpf_item_count 		= h2le16(2);				/* ALWAYS 2 */
	pccc->cpf_nai_item_type 	= h2le16(AB_EIP_ITEM_NAI);  /* ALWAYS 0 */
	pccc->cpf_nai_item_length 	= h2le16(0);   				/* ALWAYS 0 */
	pccc->cpf_udi_item_type		= h2le16(AB_EIP_ITEM_UDI);  /* ALWAYS 0x00B2 - Unconnected Data Item */
	pccc->cpf_udi_item_length	= h2le16(data - embed_start);  /* REQ: fill in with length of remaining data. */

    /* Command Routing */
    pccc->service_code = AB_EIP_CMD_PCCC_EXECUTE;  /* ALWAYS 0x4B, Execute PCCC */
    pccc->req_path_size = 2;   /* ALWAYS 2, size in words of path, next field */
    pccc->req_path[0] = 0x20;  /* class */
    pccc->req_path[1] = 0x67;  /* PCCC Execute */
    pccc->req_path[2] = 0x24;  /* instance */
    pccc->req_path[3] = 0x01;  /* instance 1 */

    /* PCCC ID */
    pccc->request_id_size = 7;  /* ALWAYS 7 */
    pccc->vendor_id = h2le16(AB_EIP_VENDOR_ID);             /* Our CIP Vendor */
    pccc->vendor_serial_number = h2le32(AB_EIP_VENDOR_SN);      /* our unique serial number */

    /* PCCC Command */
    pccc->pccc_command = AB_EIP_PCCC_TYPED_CMD;
    pccc->pccc_status = 0;  /* STS 0 in request */
    //pccc->pccc_seq_num = h2le16(tag->connection->conn_seq_num);
    pccc->pccc_function = AB_EIP_PCCC_TYPED_WRITE_FUNC;
    /* FIXME - what should be the count here?  It is bytes, 16-bit
     * words or something else?
     *
     * Seems to be the number of elements??
     */
    pccc->pccc_transfer_size = h2le16(tag->elem_count); /* This is not in the docs, but it is in the data. */


    /* get ready to add the request to the queue for this session */
    req->request_size = data - (req->data);
    req->send_request = 1;
    req->conn_seq = conn_seq_id;

    /* add the request to the session's list. */
    rc = request_add(tag->session, req);

    if(rc != PLCTAG_STATUS_OK) {
    	pdebug(debug,"Unable to lock add request to session! rc=%d",rc);
    	request_destroy(&req);
    	tag->status = rc;
    	return rc;
    }

    /* save the request for later */
    tag->reqs[0] = req;

    /* the write is now pending */
    tag->write_in_progress = 1;
    tag->status = PLCTAG_STATUS_PENDING;

    return PLCTAG_STATUS_PENDING;
}
예제 #10
0
int admin_createAccount() {
	// Variables
	char buffer[MAX_BUFFER_LEN];
	char user[MAX_USER_LEN + 1];
	char pin[MAX_PIN_LEN + 1];
	double balance;
	accountnr_t number;

	// Ask input
	cls();
	printf("Criar conta\n"
			"----------------\n");

	// Number:
	do {
		printf("Numero: ");
		gets(buffer);
		number = atoi(buffer);
	} while (strlen(buffer) > 7 || strlen(buffer) == 0 || number < 1
			|| number > 9999999 || !isInteger(buffer));

	// User
	do {
		printf("Utilizador: ");
		gets(buffer);
	} while (strlen(buffer) > 20 || strlen(buffer) < 3);
	strncpy(user, buffer, 20);
	user[20] = '\0';

	// PIN
	do {
		printf("PIN(size=4): ");
		gets(buffer);

	} while (strlen(buffer) != 4 || (strchr(buffer, ' ')) != NULL); //NO SPACES IN PIN
	strncpy(pin, buffer, 4);
	pin[4] = '\0';

	// Initial balance
	do {
		printf("Balance: ");
		gets(buffer);
		balance = atof(buffer);
	} while (balance < 0 || !isFloat(buffer));

	struct Account a;
	if (!account_create(&a, number, user, pin, balance)) {
		printf("Dados da conta invalidos!\n");
		return 1;
	} else {
		printf("echo: %s\n", account_toString(&a));

		struct Request r;
		char *msg = malloc(sizeof(char) * 10);
		char* wrStr = malloc(sizeof(char) * 128);
		sprintf(wrStr, "CREATE ACCOUNT %i %s|%s %f\n", number, user, pin,
				balance);
		request_create(&r, getpid(), "ADMIN", wrStr);
		request_writeFIFO("/tmp/requests", &r, NULL);
		request_waitFIFO(fifoname, NULL, msg);
		printf("%s\n", msg);
		getchar();

		if (strcmp(msg, "OK") == 0)
			return 1;
		else
			return 0;

	}
}
예제 #11
0
파일: request.c 프로젝트: andreiw/polaris
int request_snmpEnableAuthTraps(char *error_label)
{
	static int my_ip_address_initialized = False;
	static IPAddress my_ip_address;
	SNMP_pdu *request;
	SNMP_pdu *response;
	SNMP_variable *variable;
	int snmpEnableAuthTraps;
	struct timeval timeout;

	timeout.tv_sec = 5;
	timeout.tv_usec = 0;


	error_label[0] = '\0';

	if(my_ip_address_initialized == False)
	{
		if(get_my_ip_address(&my_ip_address, error_label))
		{
			return -1;
		}

		my_ip_address_initialized = True;
	}

	request = request_create("public", GET_REQ_MSG, error_label);
	if(request == NULL)
	{
		return -1;
	}

	if(snmp_pdu_append_null_variable(request, &snmpEnableAuthTraps_name, error_label) == NULL)
	{
		snmp_pdu_free(request);
		return -1;
	}

	response = request_send_to_port_time_out_blocking(&my_ip_address, \
		SNMP_PORT, &timeout, request, error_label);
	if(response == NULL)
	{
		snmp_pdu_free(request);
		return -1;
	}
	snmp_pdu_free(request);

	if(response->error_status)
	{
		sprintf(error_label, "%s",
			error_status_string(response->error_status));
		snmp_pdu_free(response);
		return -1;
	}

	variable = response->first_variable;
	if(variable->next_variable
		|| SSAOidCmp(&(variable->name), &snmpEnableAuthTraps_name)
		|| (variable->type != INTEGER)
		|| (variable->val.integer == NULL)
		|| (variable->val_len != sizeof(int32_t)) )
	{
		sprintf(error_label, ERR_MSG_BAD_RESPONSE);
		snmp_pdu_free(response);
		return -1;
	}
	snmpEnableAuthTraps = *(variable->val.integer);
	snmp_pdu_free(response);

	if(trace_level > 0)
	{
		trace("snmpAuthTraps: %s\n\n",
			(snmpEnableAuthTraps == 1)? "enabled(1)": "disabled(2)");
	}

	switch(snmpEnableAuthTraps)
	{
		case 1: /* enabled(1) */
			return TRUE;
		case 2: /* disable(2) */
			return FALSE;
		default:
			sprintf(error_label, ERR_MSG_BAD_VALUE);
			return -1;
	}
}
예제 #12
0
파일: request.c 프로젝트: andreiw/polaris
int32_t request_sysUpTime(char *error_label, char *community_name)
{
	static int my_ip_address_initialized = False;
	static IPAddress my_ip_address;
	SNMP_pdu *request;
	SNMP_pdu *response;
	SNMP_variable *variable;
	static int32_t sysUpTime = 0;
	static clock_t last = 0;
	clock_t now;
	struct tms buffer;


	error_label[0] = '\0';

	now = times(&buffer);
	if( (last == 0) || ((now - last) > 360000) )	/* 1 hour */
	{
		if(my_ip_address_initialized == False)
		{
			if(get_my_ip_address(&my_ip_address, error_label))
			{
				return 0;
			}

			my_ip_address_initialized = True;
		}

		if(community_name == NULL)
			request = request_create("public", GET_REQ_MSG, error_label);
		else
			request = request_create(community_name, GET_REQ_MSG, error_label);

		if(request == NULL)
		{
			return 0;
		}

		if(snmp_pdu_append_null_variable(request, &sysUptime_instance, error_label) == NULL)
		{
			snmp_pdu_free(request);
			return 0;
		}

		response = request_send_blocking(&my_ip_address, request, error_label);
		if(response == NULL)
		{
			snmp_pdu_free(request);
			return 0;
		}
		snmp_pdu_free(request);

		if(response->error_status)
		{
			sprintf(error_label, "%s",
				error_status_string(response->error_status));
			snmp_pdu_free(response);
			return 0;
		}

		variable = response->first_variable;
		if(variable->next_variable
			|| SSAOidCmp(&(variable->name), &sysUptime_instance)
			|| (variable->type != TIMETICKS)
			|| (variable->val.integer == NULL)
			|| (variable->val_len != sizeof(int32_t)) )
		{
			sprintf(error_label, ERR_MSG_BAD_RESPONSE);
			snmp_pdu_free(response);
			return 0;
		}
		sysUpTime = *(variable->val.integer);
		last = now;
		snmp_pdu_free(response);

		if(trace_level > 0)
		{
			trace("sysUpTime: %d\n\n", sysUpTime);
		}

		return sysUpTime;
	}

	/* LINTED */
	return (sysUpTime + (int32_t)(now - last));
}
예제 #13
0
int build_write_request(ab_tag_p tag, int slot, int byte_offset)
{
	int rc = PLCTAG_STATUS_OK;
	int debug = tag->debug;
    eip_cip_uc_req *cip;
    uint8_t *data;
    uint8_t *embed_start, *embed_end;
    ab_request_p req = NULL;

    pdebug(debug,"Starting.");

	/* get a request buffer */
	rc = request_create(&req);

	if(rc != PLCTAG_STATUS_OK) {
		pdebug(debug,"Unable to get new request.  rc=%d",rc);
		tag->status = rc;
		return rc;
	}

	/* set debug flag on the request too */
	req->debug = tag->debug;

	cip = (eip_cip_uc_req*)(req->data);

	/* point to the end of the struct */
	data = (req->data) + sizeof(eip_cip_uc_req);

	/*
	 * set up the embedded CIP read packet
	 * The format is:
	 *
	 * uint8_t cmd
	 * LLA formatted name
	 * data type to write
	 * uint16_t # of elements to write
	 * data to write
	 */

	embed_start = data;

	/*
	 * set up the CIP Read request type.
	 * Different if more than one request.
	 *
	 * This handles a bug where attempting fragmented requests
	 * does not appear to work with a single boolean.
	 */
	*data = (tag->num_write_requests > 1) ? AB_EIP_CMD_CIP_WRITE_FRAG : AB_EIP_CMD_CIP_WRITE;
	data++;

	/* copy the tag name into the request */
	mem_copy(data,tag->encoded_name,tag->encoded_name_size);
	data += tag->encoded_name_size;

	/* copy encoded type info */
	if(tag->encoded_type_info_size) {
		mem_copy(data,tag->encoded_type_info,tag->encoded_type_info_size);
		data += tag->encoded_type_info_size;
	} else {
		tag->status = PLCTAG_ERR_UNSUPPORTED;
		return tag->status;
	}

	/* copy the item count, little endian */
	*((uint16_t*)data) = h2le16(tag->elem_count);
	data += 2;

	if(tag->num_write_requests > 1) {
		/* put in the byte offset */
		*((uint32_t*)data) = h2le32(byte_offset);
		data += 4;
	}

	/* now copy the data to write */
	mem_copy(data, tag->data + byte_offset, tag->write_req_sizes[slot]);
	data += tag->write_req_sizes[slot];

	/* need to pad data to multiple of 16-bits */
	if(tag->write_req_sizes[slot] & 0x01) {
		*data = 0;
		data++;
	}

	/* mark the end of the embedded packet */
	embed_end = data;

	/*
	 * after the embedded packet, we need to tell the message router
	 * how to get to the target device.
	 */

	/* Now copy in the routing information for the embedded message */
	*data = (tag->conn_path_size)/2; /* in 16-bit words */
	data++;
	*data = 0;
	data++;
	mem_copy(data,tag->conn_path, tag->conn_path_size);
	data += tag->conn_path_size;

	/* now fill in the rest of the structure. */

	/* encap fields */
	cip->encap_command = h2le16(AB_EIP_READ_RR_DATA);    /* ALWAYS 0x006F Unconnected Send*/

	/* router timeout */
	cip->router_timeout = h2le16(1);                 /* one second timeout, enough? */

	/* Common Packet Format fields for unconnected send. */
	cip->cpf_item_count 		= h2le16(2);				/* ALWAYS 2 */
	cip->cpf_nai_item_type 		= h2le16(AB_EIP_ITEM_NAI);  /* ALWAYS 0 */
	cip->cpf_nai_item_length 	= h2le16(0);   				/* ALWAYS 0 */
	cip->cpf_udi_item_type		= h2le16(AB_EIP_ITEM_UDI);  /* ALWAYS 0x00B2 - Unconnected Data Item */
	cip->cpf_udi_item_length	= h2le16(data - (uint8_t*)(&(cip->cm_service_code)));  /* REQ: fill in with length of remaining data. */

	/* CM Service Request - Connection Manager */
	cip->cm_service_code = AB_EIP_CMD_UNCONNECTED_SEND;        /* 0x52 Unconnected Send */
	cip->cm_req_path_size = 2;   /* 2, size in 16-bit words of path, next field */
	cip->cm_req_path[0] = 0x20;  /* class */
	cip->cm_req_path[1] = 0x06;  /* Connection Manager */
	cip->cm_req_path[2] = 0x24;  /* instance */
	cip->cm_req_path[3] = 0x01;  /* instance 1 */

	/* Unconnected send needs timeout information */
	cip->secs_per_tick = AB_EIP_SECS_PER_TICK;	/* seconds per tick */
	cip->timeout_ticks = AB_EIP_TIMEOUT_TICKS;  /* timeout = srd_secs_per_tick * src_timeout_ticks */

	/* size of embedded packet */
	cip->uc_cmd_length = h2le16(embed_end - embed_start);

	/* set the size of the request */
	req->request_size = data - (req->data);

	/* mark it as ready to send */
	req->send_request = 1;

	/* add the request to the session's list. */
	rc = request_add(tag->session, req);

	if(rc != PLCTAG_STATUS_OK) {
		pdebug(debug,"Unable to lock add request to session! rc=%d",rc);
		plc_tag_abort((plc_tag)tag);
		request_destroy(&req);
		tag->status = rc;
		return rc;
	}

	/* save the request for later */
	tag->reqs[slot] = req;

	pdebug(debug,"Done");

	return PLCTAG_STATUS_OK;
}
예제 #14
0
int build_read_request(ab_tag_p tag, int slot, int byte_offset)
{
    eip_cip_uc_req *cip;
    uint8_t *data;
    uint8_t *embed_start, *embed_end;
    ab_request_p req = NULL;
    int debug = tag->debug;
    int rc;

    pdebug(debug,"Starting.");

	/* get a request buffer */
	rc = request_create(&req);

	if(rc != PLCTAG_STATUS_OK) {
		pdebug(debug,"Unable to get new request.  rc=%d",rc);
		tag->status = rc;
		return rc;
	}

	req->debug = debug;

	/* point the request struct at the buffer */
	cip = (eip_cip_uc_req*)(req->data);

	/* point to the end of the struct */
	data = (req->data) + sizeof(eip_cip_uc_req);


	/*
	 * set up the embedded CIP read packet
	 * The format is:
	 *
	 * uint8_t cmd
	 * LLA formatted name
	 * uint16_t # of elements to read
	 */

	embed_start = data;

	/* set up the CIP Read request */
	*data = AB_EIP_CMD_CIP_READ_FRAG;
	data++;

	/* copy the tag name into the request */
	mem_copy(data,tag->encoded_name,tag->encoded_name_size);
	data += tag->encoded_name_size;

	/* add the count of elements to read. */
	*((uint16_t*)data) = h2le16(tag->elem_count);
	data += sizeof(uint16_t);

	/* add the byte offset for this request */
	*((uint32_t*)data) = h2le32(byte_offset);
	data += sizeof(uint32_t);

	/* mark the end of the embedded packet */
	embed_end = data;

	/* Now copy in the routing information for the embedded message */
	/*
	 * routing information.  Format:
	 *
	 * uint8_t path_size in 16-bit words
	 * uint8_t reserved/pad (zero)
	 * uint8_t[...] path (padded to even number of bytes)
	 */
	*data = (tag->conn_path_size)/2; /* in 16-bit words */
	data++;
	*data = 0; /* reserved/pad */
	data++;
	mem_copy(data, tag->conn_path, tag->conn_path_size);
	data += tag->conn_path_size;

	/* now we go back and fill in the fields of the static part */

	/* encap fields */
	cip->encap_command = h2le16(AB_EIP_READ_RR_DATA);    /* ALWAYS 0x0070 Unconnected Send*/

	/* router timeout */
	cip->router_timeout = h2le16(1);                 /* one second timeout, enough? */

	/* Common Packet Format fields for unconnected send. */
	cip->cpf_item_count 		= h2le16(2);				/* ALWAYS 2 */
	cip->cpf_nai_item_type 		= h2le16(AB_EIP_ITEM_NAI);  /* ALWAYS 0 */
	cip->cpf_nai_item_length 	= h2le16(0);   				/* ALWAYS 0 */
	cip->cpf_udi_item_type		= h2le16(AB_EIP_ITEM_UDI);  /* ALWAYS 0x00B2 - Unconnected Data Item */
	cip->cpf_udi_item_length	= h2le16(data - (uint8_t*)(&(cip->cm_service_code)));  /* REQ: fill in with length of remaining data. */

	/* CM Service Request - Connection Manager */
	cip->cm_service_code = AB_EIP_CMD_UNCONNECTED_SEND;        /* 0x52 Unconnected Send */
	cip->cm_req_path_size = 2;   /* 2, size in 16-bit words of path, next field */
	cip->cm_req_path[0] = 0x20;  /* class */
	cip->cm_req_path[1] = 0x06;  /* Connection Manager */
	cip->cm_req_path[2] = 0x24;  /* instance */
	cip->cm_req_path[3] = 0x01;  /* instance 1 */

	/* Unconnected send needs timeout information */
	cip->secs_per_tick = AB_EIP_SECS_PER_TICK;	/* seconds per tick */
	cip->timeout_ticks = AB_EIP_TIMEOUT_TICKS;  /* timeout = src_secs_per_tick * src_timeout_ticks */

	/* size of embedded packet */
	cip->uc_cmd_length = h2le16(embed_end - embed_start);

	/* set the size of the request */
	req->request_size = data - (req->data);

	/* mark it as ready to send */
	req->send_request = 1;

	/* add the request to the session's list. */
	rc = request_add(tag->session, req);

	if(rc != PLCTAG_STATUS_OK) {
		pdebug(debug,"Unable to add request to session! rc=%d",rc);
		request_destroy(&req);
		tag->status = rc;
		return rc;
	}

	/* save the request for later */
	tag->reqs[slot] = req;

	pdebug(debug,"Done");

	return PLCTAG_STATUS_OK;
}