/* ip_addr is now in network byte order * * first we have to get hold of the portnumber to * the node through epmd at that host * */ int ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr adr, char *alivename, unsigned ms) { struct in_addr *ip_addr=(struct in_addr *) adr; int rport = 0; /*uint16 rport = 0;*/ int sockd; int one = 1; int dist = 0; ErlConnect her_name; unsigned her_flags, her_version; erl_errno = EIO; /* Default error code */ EI_TRACE_CONN1("ei_xconnect","-> CONNECT attempt to connect to %s", alivename); if ((rport = ei_epmd_port_tmo(ip_addr,alivename,&dist, ms)) < 0) { EI_TRACE_ERR0("ei_xconnect","-> CONNECT can't get remote port"); /* ei_epmd_port_tmo() has set erl_errno */ return ERL_NO_PORT; } /* we now have port number to enode, try to connect */ if((sockd = cnct((uint16)rport, ip_addr, sizeof(struct in_addr),ms)) < 0) { EI_TRACE_ERR0("ei_xconnect","-> CONNECT socket connect failed"); /* cnct() has set erl_errno */ return ERL_CONNECT_FAIL; } EI_TRACE_CONN0("ei_xconnect","-> CONNECT connected to remote"); /* FIXME why connect before checking 'dist' output from ei_epmd_port() ?! */ if (dist <= 4) { EI_TRACE_ERR0("ei_xconnect","-> CONNECT remote version not compatible"); goto error; } else { unsigned our_challenge, her_challenge; unsigned char our_digest[16]; if (send_name(sockd, ec->thisnodename, (unsigned) dist, ms)) goto error; if (recv_status(sockd, ms)) goto error; if (recv_challenge(sockd, &her_challenge, &her_version, &her_flags, &her_name, ms)) goto error; our_challenge = gen_challenge(); gen_digest(her_challenge, ec->ei_connect_cookie, our_digest); if (send_challenge_reply(sockd, our_digest, our_challenge, ms)) goto error; if (recv_challenge_ack(sockd, our_challenge, ec->ei_connect_cookie, ms)) goto error; put_ei_socket_info(sockd, dist, null_cookie, ec); /* FIXME check == 0 */ } setsockopt(sockd, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)); setsockopt(sockd, SOL_SOCKET, SO_KEEPALIVE, (char *)&one, sizeof(one)); EI_TRACE_CONN1("ei_xconnect","-> CONNECT (ok) remote = %s",alivename); erl_errno = 0; return sockd; error: EI_TRACE_ERR0("ei_xconnect","-> CONNECT failed"); closesocket(sockd); return ERL_ERROR; } /* ei_xconnect */
static void recv_response(struct ste_message *msg) { uint32_t status; uint8_t *param; DBG_VERBOSE("msg_id 0x%x", msg->id); if (msg->id == STE_END_SAP_RSP) { sap_disconnect_rsp(u8500.sap_data); simd_close(); return; } param = msg->payload; status = *(uint32_t *)param; param += sizeof(status); DBG_VERBOSE("status 0x%x", status); switch (msg->id) { case STE_START_SAP_RSP: if (status == STE_STATUS_OK) { sap_connect_rsp(u8500.sap_data, SAP_STATUS_OK, 0); } else { sap_connect_rsp(u8500.sap_data, SAP_STATUS_CONNECTION_FAILED, 0); simd_close(); } break; case STE_SEND_APDU_RSP: recv_pdu(STE_SEND_APDU_MSG, msg, status, param, sap_transfer_apdu_rsp); break; case STE_GET_ATR_RSP: recv_pdu(STE_GET_ATR_MSG, msg, status, param, sap_transfer_atr_rsp); break; case STE_POWER_OFF_RSP: recv_state_change(STE_POWER_OFF_MSG, status, STE_POWERED_OFF, sap_power_sim_off_rsp); break; case STE_POWER_ON_RSP: recv_state_change(STE_POWER_ON_MSG, status, STE_ENABLED, sap_power_sim_on_rsp); break; case STE_RESET_RSP: recv_state_change(STE_RESET_MSG, status, STE_ENABLED, sap_reset_sim_rsp); break; case STE_GET_STATUS_RSP: recv_card_status(status, param); break; case STE_STATUS_IND: recv_status(status); break; default: sap_error("unsupported message received (id 0x%x)", msg->id); } }
int main (int argc, char * argv []) { int err = -1; int f = -1; while (1) { if (argc != 3) break; word_t segment = 0; word_t offset = 0; sscanf (argv [2], "%hx:%hx", &segment, &offset); f = open (argv [1], O_RDWR | O_NOCTTY); if (f < 0) { perror ("open tty"); break; } _fi = f; _fo = f; // TTY setup struct termios tios; tcgetattr (f, &tios); //cfmakeraw (&tios); cfsetspeed (&tios, B9600); tcsetattr (f, TCSANOW, &tios); byte_t len; byte_t token [TOKEN_LEN_MAX]; // Check header err = send_value (0); if (err) { perror ("send header"); break; } err = recv_status (); if (err) { perror ("receive status header"); break; } // Set segment and offset err = send_value (segment); if (err) break; err = recv_status (); if (err) { perror ("receive status segment"); break; } err = send_command ('W', '8'); // ES register if (err) break; err = recv_status (); if (err) { perror ("receive status W8"); break; } err = send_value (offset); if (err) break; err = recv_status (); if (err) { perror ("receive status offset"); break; } err = send_command ('W', '5'); // DI register if (err) break; err = recv_status (); if (err) { perror ("receive status W5"); break; } while (1) { word_t val; int n = read (0, &val, 1); if (n != 1) break; err = send_value (val); if (err) { perror ("send value"); break; } err = recv_status (); if (err) { perror ("receive status value"); break; } err = send_command ('X', '1'); // write command if (err) break; err = recv_status (); if (err) { perror ("receive status X1"); break; } } break; } // Cleanup _fi = -1; _fo = -1; if (f) { close (f); f = -1; } return err; }