int open_path(const char * path, int print) { int device = async_open_path(path, print); if(device >= 0) { HIDD_ATTRIBUTES attributes = { .Size = sizeof(HIDD_ATTRIBUTES) }; if(HidD_GetAttributes(devices[device].handle, &attributes) == TRUE) { PHIDP_PREPARSED_DATA preparsedData; HIDP_CAPS hidCapabilities; if(HidD_GetPreparsedData(devices[device].handle, &preparsedData) == TRUE) { if(HidP_GetCaps(preparsedData, &hidCapabilities) == HIDP_STATUS_SUCCESS ) { devices[device].write.size = hidCapabilities.OutputReportByteLength; async_set_read_size(device, hidCapabilities.InputReportByteLength); devices[device].hidInfo.vendor_id = attributes.VendorID; devices[device].hidInfo.product_id = attributes.ProductID; devices[device].hidInfo.bcdDevice = attributes.VersionNumber; } else { if (print) { ASYNC_PRINT_ERROR("HidP_GetCaps") } async_close(device); device = -1; } HidD_FreePreparsedData(preparsedData); } else { if (print) { ASYNC_PRINT_ERROR("HidD_GetPreparsedData") } async_close(device); device = -1; } }
void async_clean(void) { int i; for (i = 0; i < ASYNC_MAX_DEVICES; ++i) { if(devices[i].fd >= 0) { async_close(i); } } }
int connection_t::on_recv_data() { LOGTRACE((CONNECTION_MODULE, "connection_t::on_recv_data begin")); if (m_enable_hb) { m_service_ptr->async_update_hb_element(m_conn_id); } int recv_ret = 0; int ret = m_read_buffer.recv_to_buffer(m_socket, recv_ret); if (-1 == ret) { //! yunjie: 内存分配失败, 必须回调callback, 否则buffer满了将陷入死循环 LOGWARN((CONNECTION_MODULE, "connection_t::on_recv_data recv_to_buffer failed socket fd:[%u] read buf data size:[%u]", m_socket, m_read_buffer.size() )); on_read_complete(m_read_buffer); return 0; } if (0 == recv_ret) { LOGWARN((CONNECTION_MODULE, "connection_t::on_recv_data recv_ret == 0 socket fd:[%u]", m_socket)); async_close(m_conn_id, true, EV_PASSIVE_CLOSED); return 0; } else if (recv_ret < 0) { //! yunjie: 如果不是EAGAIN或EINTR, 那么就调用callback返回错误信息 if (errno != EAGAIN && errno != EINTR) { if (NULL != m_conn_event_callback) { m_conn_event_callback(EV_ERROR_OCCURRED, m_conn_status, m_conn_id, m_user_data); } } LOGWARN((CONNECTION_MODULE, "connection_t::on_recv_data recv_ret:[%d] socket fd:[%u] errno:[%s]", recv_ret, m_socket, STRERR)); return 0; } else { //! yunjie: 使用者可以实现的虚方法 on_read_complete(m_read_buffer); } LOGTRACE((CONNECTION_MODULE, "connection_t::on_recv_data end")); return 0; }
/* * \brief Open a hid device. * * \param vendor the vendor id of the hid device to open. * \param product the product id of the hid device to open. * * \return the identifier of the opened device (to be used in further operations), \ * or -1 in case of failure (e.g. no device found). */ int hidasync_open_ids(unsigned short vendor, unsigned short product) { int ret = -1; GUID guid; HDEVINFO info; DWORD reqd_size; SP_DEVICE_INTERFACE_DATA iface; SP_DEVICE_INTERFACE_DETAIL_DATA *details; int index; HidD_GetHidGuid(&guid); info = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if(info != INVALID_HANDLE_VALUE) { for(index = 0; ; ++index) { iface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); if(SetupDiEnumDeviceInterfaces(info, NULL, &guid, index, &iface) == FALSE) { break; //no more device } if(SetupDiGetInterfaceDeviceDetail(info, &iface, NULL, 0, &reqd_size, NULL) == FALSE) { if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) { continue; } } details = calloc(reqd_size, sizeof(char)); if(details == NULL) { fprintf(stderr, "%s:%d calloc failed\n", __FILE__, __LINE__); continue; } details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if(SetupDiGetDeviceInterfaceDetail(info, &iface, details, reqd_size, NULL, NULL) == FALSE) { ASYNC_PRINT_ERROR("SetupDiGetDeviceInterfaceDetail") free(details); details = NULL; continue; } int device = open_path(details->DevicePath, 0); free(details); details = NULL; if(device >= 0) { if(devices[device].hidInfo.vendor_id == vendor && devices[device].hidInfo.product_id == product) { ret = device; break; } async_close(device); } } } return ret; }
void SocketFree(SocketRef *const socketptr) { SocketRef socket = *socketptr; if(!socket) return; if(socket->secure) tls_close(socket->secure); tls_free(socket->secure); socket->secure = NULL; async_close((uv_handle_t *)socket->stream); FREE(&socket->rdmem); socket->rd->base = NULL; socket->rd->len = 0; FREE(&socket->wr->base); socket->wr->len = 0; socket->err = 0; assert_zeroed(socket, 1); FREE(socketptr); socket = NULL; }
int asyncCmd(char **argv,unsigned short argc){ char c; CTL_EVENT_SET_t e=0,evt; unsigned char addr; if(argc!=0){ printf("Error : \"%s\" takes zero arguments\r\n",argv[0]); return -1; } //close async connection if(async_close()!=RET_SUCCESS){ printf("Error : async_close() failed.\r\n"); } }
static void term(void *const unused) { fprintf(stderr, "\nStopping StrongLink server...\n"); uv_ref((uv_handle_t *)sigint); uv_signal_stop(sigint); async_close((uv_handle_t *)sigint); SLNRepoPullsStop(repo); HTTPServerClose(server_raw); HTTPServerClose(server_tls); uv_ref((uv_handle_t *)sigpipe); uv_signal_stop(sigpipe); uv_close((uv_handle_t *)sigpipe, NULL); }
int async_poll_socket(uv_os_sock_t const socket, int *const events) { assert(events); struct poll_state state[1]; state->thread = async_active(); state->status = 0; state->events = 0; uv_poll_t poll[1]; poll->data = state; int rc = uv_poll_init_socket(async_loop, poll, socket); if(rc < 0) return rc; rc = uv_poll_start(poll, *events, poll_cb); if(rc < 0) return rc; async_yield(); async_close((uv_handle_t *)poll); *events = state->events; return state->status; }
static void term(void *const unused) { fprintf(stderr, "\n"); alogf("Stopping StrongLink server...\n"); uv_ref((uv_handle_t *)sigint); uv_signal_stop(sigint); async_close((uv_handle_t *)sigint); SLNRepoPullsStop(repo); HTTPServerClose(server_raw); HTTPServerClose(server_tls); async_pool_enter(NULL); fflush(NULL); // Everything. async_pool_leave(NULL); uv_ref((uv_handle_t *)sigpipe); uv_signal_stop(sigpipe); uv_close((uv_handle_t *)sigpipe, NULL); }
//reset a MSP430 on command int restCmd(char **argv,unsigned short argc){ unsigned char buff[10]; unsigned char addr; unsigned short all=0; int resp; //force user to pass no arguments to prevent unwanted resets if(argc>1){ puts("Error : too many arguments\r"); return -1; } if(argc!=0){ if(!strcmp(argv[1],"all")){ all=1; addr=BUS_ADDR_GC; }else{ //get address addr=getI2C_addr(argv[1],0); if(addr==0xFF){ return 1; } } //setup packet BUS_cmd_init(buff,CMD_RESET); resp=BUS_cmd_tx(addr,buff,0,0,BUS_I2C_SEND_FOREGROUND); switch(resp){ case 0: puts("Command Sent Sucussfully.\r"); break; } } //reset if no arguments given or to reset all boards if(argc==0 || all){ //Close async connection async_close(); //write to WDTCTL without password causes PUC reset(ERR_LEV_INFO,SDTST_ERR_SRC_CMD,CMD_ERR_RESET,0); //Never reached due to reset puts("Error : Reset Failed!\r"); } return 0; }
int HTTPServerListen(HTTPServerRef const server, strarg_t const address, strarg_t const port) { if(!server) return 0; assertf(!server->socket->data, "HTTPServer already listening"); int rc; rc = uv_tcp_init(async_loop, server->socket); if(rc < 0) return rc; server->socket->data = server; struct addrinfo const hints = { .ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_NUMERICSERV | AI_PASSIVE, .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM, .ai_protocol = 0, // ??? }; struct addrinfo *info; rc = async_getaddrinfo(address, port, &hints, &info); if(rc < 0) { HTTPServerClose(server); return rc; } int bound = 0; rc = 0; for(struct addrinfo *each = info; each; each = each->ai_next) { rc = uv_tcp_bind(server->socket, each->ai_addr, 0); if(rc >= 0) bound++; } uv_freeaddrinfo(info); if(!bound) { HTTPServerClose(server); if(rc < 0) return rc; return UV_EADDRNOTAVAIL; } rc = uv_listen((uv_stream_t *)server->socket, 511, connection_cb); if(rc < 0) { HTTPServerClose(server); return rc; } return 0; } int HTTPServerListenSecure(HTTPServerRef const server, strarg_t const address, strarg_t const port, struct tls **const tlsptr) { if(!server) return 0; int rc = HTTPServerListen(server, address, port); if(rc < 0) return rc; server->secure = *tlsptr; *tlsptr = NULL; return 0; } void HTTPServerClose(HTTPServerRef const server) { if(!server) return; if(!server->socket->data) return; if(server->secure) tls_close(server->secure); tls_free(server->secure); server->secure = NULL; async_close((uv_handle_t *)server->socket); } static void connection(uv_stream_t *const socket) { HTTPServerRef const server = socket->data; HTTPConnectionRef conn; int rc = HTTPConnectionCreateIncomingSecure(socket, server->secure, 0, &conn); if(rc < 0) { fprintf(stderr, "HTTP server connection error %s\n", uv_strerror(rc)); return; } assert(conn); for(;;) { server->listener(server->context, server, conn); rc = HTTPConnectionDrainMessage(conn); if(rc < 0) break; } HTTPConnectionFree(&conn); }
s_hid_dev * hidasync_enumerate(unsigned short vendor, unsigned short product) { s_hid_dev * hid_devs = NULL; unsigned int nb_hid_devs = 0; GUID guid; HidD_GetHidGuid(&guid); HDEVINFO info = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if(info != INVALID_HANDLE_VALUE) { int index; for(index = 0; ; ++index) { SP_DEVICE_INTERFACE_DATA iface; iface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); if(SetupDiEnumDeviceInterfaces(info, NULL, &guid, index, &iface) == FALSE) { break; //no more device } DWORD reqd_size; if(SetupDiGetInterfaceDeviceDetail(info, &iface, NULL, 0, &reqd_size, NULL) == FALSE) { if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) { continue; } } SP_DEVICE_INTERFACE_DETAIL_DATA * details = calloc(reqd_size, sizeof(char)); if(details == NULL) { fprintf(stderr, "%s:%d calloc failed\n", __FILE__, __LINE__); continue; } details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if(SetupDiGetDeviceInterfaceDetail(info, &iface, details, reqd_size, NULL, NULL) == FALSE) { ASYNC_PRINT_ERROR("SetupDiGetDeviceInterfaceDetail") free(details); continue; } int device = open_path(details->DevicePath, 0); free(details); if(device >= 0) { if(vendor) { if (devices[device].hidInfo.vendor_id != vendor) { async_close(device); continue; } if(product) { if(devices[device].hidInfo.product_id != product) { async_close(device); continue; } } } char * path = strdup(devices[device].path); if(path == NULL) { PRINT_ERROR_OTHER("strdup failed") async_close(device); continue; } void * ptr = realloc(hid_devs, (nb_hid_devs + 1) * sizeof(*hid_devs)); if(ptr == NULL) { PRINT_ERROR_ALLOC_FAILED("realloc") free(path); async_close(device); continue; } hid_devs = ptr; if(nb_hid_devs > 0) { hid_devs[nb_hid_devs - 1].next = 1; } hid_devs[nb_hid_devs].path = path; hid_devs[nb_hid_devs].vendor_id = devices[device].hidInfo.vendor_id; hid_devs[nb_hid_devs].product_id = devices[device].hidInfo.product_id; hid_devs[nb_hid_devs].next = 0; ++nb_hid_devs; async_close(device); } } } return hid_devs; }
int connection_t::on_send_data() { LOGTRACE((CONNECTION_MODULE, "connection_t::on_send_data begin")); if (m_enable_hb) { m_service_ptr->async_update_hb_element(m_conn_id); } uint32_t transferred_size = 0; while (m_write_buffer.size()) { uint32_t msg_size = m_write_buffer.size(); int32_t ret = ::send(m_socket, m_write_buffer.data(), msg_size, 0); if (0 == ret) { LOGWARN((CONNECTION_MODULE, "connection_t::on_send_data send ret == 0 socket fd:[%u]", m_socket)); async_close(m_conn_id, true, EV_PASSIVE_CLOSED); return 0; } else if (ret < 0) { if (EINTR == errno) { //! yunjie: 立刻重新send LOGWARN((CONNECTION_MODULE, "connection_t::on_send_data recv EINTR send ret:[%d] socket fd:[%u] errno:[%s]", ret, m_socket, STRERR )); continue; } else if (EAGAIN == errno) { //! yunjie: 重新注册I/O事件 m_service_ptr->register_io_event( m_socket, WRITE_EVENT_FLAG, &connection_t::on_peer_event, (void*)this, false ); } else { //! yunjie: 非EINTR,非EAGAIN, 调用上层错误处理函数 if (NULL != m_conn_event_callback) { m_conn_event_callback(EV_ERROR_OCCURRED, m_conn_status, m_conn_id, m_user_data); } } LOGWARN((CONNECTION_MODULE, "connection_t::on_send_data send ret:[%d] socket fd:[%u] errno:[%s]", ret, m_socket, STRERR )); break; } else { transferred_size += ret; m_write_buffer.drain_size(ret); if (ret != (int32_t)msg_size) { m_service_ptr->register_io_event( m_socket, WRITE_EVENT_FLAG, &connection_t::on_peer_event, (void*)this, false ); break; } } } if (transferred_size) { //! yunjie: 使用者可以实现的虚方法 on_write_complete(transferred_size); } if (!m_write_buffer.size()) { m_sending_flag = false; } LOGTRACE((CONNECTION_MODULE, "connection_t::on_send_data end")); return 0; }
int HTTPConnectionCreateOutgoing(strarg_t const domain, unsigned const flags, HTTPConnectionRef *const out) { str_t host[1023+1]; str_t service[15+1]; host[0] = '\0'; service[0] = '\0'; int matched = sscanf(domain, "%1023[^:]:%15[0-9]", host, service); if(matched < 1) return UV_EINVAL; if('\0' == host[0]) return UV_EINVAL; static struct addrinfo const hints = { .ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_NUMERICSERV, .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM, .ai_protocol = 0, // ??? }; struct addrinfo *info = NULL; HTTPConnectionRef conn = NULL; int rc; rc = async_getaddrinfo(host, service[0] ? service : "80", &hints, &info); if(rc < 0) goto cleanup; conn = calloc(1, sizeof(struct HTTPConnection)); if(!conn) rc = UV_ENOMEM; if(rc < 0) goto cleanup; rc = UV_EADDRNOTAVAIL; for(struct addrinfo *each = info; each; each = each->ai_next) { rc = uv_tcp_init(async_loop, conn->stream); if(rc < 0) break; rc = async_tcp_connect(conn->stream, each->ai_addr); if(rc >= 0) break; async_close((uv_handle_t *)conn->stream); } if(rc < 0) goto cleanup; http_parser_init(conn->parser, HTTP_RESPONSE); conn->parser->data = conn; *out = conn; conn = NULL; cleanup: uv_freeaddrinfo(info); info = NULL; HTTPConnectionFree(&conn); return rc; } void HTTPConnectionFree(HTTPConnectionRef *const connptr) { HTTPConnectionRef conn = *connptr; if(!conn) return; async_close((uv_handle_t *)conn->stream); // http_parser does not need to be freed, closed or destroyed. memset(conn->parser, 0, sizeof(*conn->parser)); FREE(&conn->buf); *conn->raw = uv_buf_init(NULL, 0); conn->type = HTTPNothing; *conn->out = uv_buf_init(NULL, 0); conn->flags = 0; assert_zeroed(conn, 1); FREE(connptr); conn = NULL; }
int connection_t::on_send_data() { if (m_enable_hb) { m_service_ptr->async_update_hb_element(m_conn_id); } bool all_finish = true; int transferred_size = 0; while (m_send_buffer.size()) { uint32_t msg_size = m_send_buffer.size(); int ret = ::send(m_socket, m_send_buffer.data(), msg_size, 0); if (0 == ret) { LOGWARN((CONNECTION_MODULE, "connection_t::on_send_data send ret == 0 socket fd:[%u]", m_socket)); async_close(m_conn_id, true, EV_PASSIVE_CLOSED); return 0; } else if (ret < 0) { LOGWARN((CONNECTION_MODULE, "connection_t::on_send_data send ret:[%d] socket fd:[%u] errno:[%m]", ret, m_socket, errno)); //! yunjie: 如果不是EAGAIN或EINTR, 那么就调用callback返回错误信息 if (errno != EAGAIN && errno != EINTR) { if (NULL != m_conn_event_callback) { m_conn_event_callback(EV_ERROR_OCCURRED, m_conn_status, m_conn_id); } } else { m_service_ptr->register_io_event( m_socket, WRITE_EVENT_FLAG, &connection_t::on_peer_event, (void*)this, false ); } return 0; } else { transferred_size += ret; m_send_buffer.drain_size(ret); if (ret != (int)msg_size) { m_service_ptr->register_io_event( m_socket, WRITE_EVENT_FLAG, &connection_t::on_peer_event, (void*)this, false ); all_finish = false; break; } } } //! yunjie: 使用者可以实现的虚方法 on_write_complete(transferred_size); if (all_finish) { m_sending_flag = false; } return 0; }