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; }
/* * utilities */ static void test_setup(void) { req = request_create(); rsp = response_create(); buf = buf_create(); }
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(); }
/* * 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; }
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; }
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; }
/* * 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; }
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; }
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; }
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; } }
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; } }
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)); }
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; }
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; }