static wrapd_status_t wrapd_wpa_s_cmd(wrapd_hdl_t *mctx, char *cmd) { struct wrap_demon *aptr = (void *) mctx; char buf[2048]; size_t len = sizeof(buf); int ret; if (aptr->global == NULL) { wrapd_printf("Not connected to global wpa_supplicant"); return -1; } ret = wpa_ctrl_request(aptr->global, cmd, os_strlen(cmd), buf, &len, NULL); if (ret == -2) { wrapd_printf("'%s' command timed out", cmd); return WRAPD_STATUS_ETIMEDOUT; } else if (ret < 0) { wrapd_printf("'%s' command failed", cmd); return WRAPD_STATUS_FAILED; } buf[len] = '\0'; //wrapd_printf("%s", buf); return WRAPD_STATUS_OK; }
/* ----------------------------------------------------------------------------- WPACtrl_request */ static PyObject* WPACtrl_request(WPACtrl* self, PyObject* args, UNUSED PyObject* kargs) { int ret; char* cmd; char buf[2048]; size_t buflen = sizeof(buf) - 1; if (!PyArg_ParseTuple(args, "s", &cmd)) { PyErr_SetString(WPACtrl_error, "failed to parse request command string"); return NULL; } ret = wpa_ctrl_request(self->ctrl_iface, cmd, strlen(cmd), buf, &buflen, NULL); switch (ret) { case 0: buf[buflen] = '\0'; return Py_BuildValue("s", buf); case -1: PyErr_SetString(WPACtrl_error, "wpa_ctrl_request failed"); break; case -2: PyErr_SetString(WPACtrl_error, "wpa_ctrl_request timed out"); break; default: PyErr_SetString(WPACtrl_error, "wpa_ctrl_request returned unknown error"); break; } return NULL; }
S32 IpcWpa_CommandWithResp(THandle hIpcWpa, PS8 cmd, S32 print, PS8 pResp, PU32 pRespLen) { TIpcWpa* pIpcWpa = (TIpcWpa*)hIpcWpa; S32 ret; *pRespLen = IPC_WPA_RESP_MAX_LEN - 1; ret = wpa_ctrl_request(pIpcWpa->pWpaCtrl, (char*)cmd, os_strlen(cmd), (char*)pResp, (size_t*)pRespLen, NULL); if (ret == -2) { os_error_printf(CU_MSG_ERROR, (PS8)"'%s' command timed out.\n", cmd); return EOALERR_IPC_WPA_ERROR_CMD_TIMEOUT; } else if (ret < 0) { os_error_printf(CU_MSG_ERROR, (PS8)"'%s' command failed.\n", cmd); return EOALERR_IPC_WPA_ERROR_CMD_FAILED; } if (print) { pResp[*pRespLen] = '\0'; os_error_printf(CU_MSG_INFO2, (PS8)"%s", pResp); } return OK; }
static void do_wpa_request(char *cmd, size_t len) { size_t reply_len = sizeof(wpa_buffer); if (wpa_ctrl_request(ctrl, cmd, len, wpa_buffer, &reply_len, send_to_erl) < 0) err(EXIT_FAILURE, "wpa_ctrl_request"); send_to_erl(wpa_buffer, reply_len); }
static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, const char *cmd, char *addr, size_t addr_len, int print) { char buf[4096], *pos; size_t len; int ret; if (ctrl_conn == NULL) { printf("Not connected to hostapd - command dropped.\n"); return -1; } len = sizeof(buf) - 1; ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, hostapd_cli_msg_cb); if (ret == -2) { printf("'%s' command timed out.\n", cmd); return -2; } else if (ret < 0) { printf("'%s' command failed.\n", cmd); return -1; } buf[len] = '\0'; if (memcmp(buf, "FAIL", 4) == 0) return -1; if (print) printf("%s", buf); pos = buf; while (*pos != '\0' && *pos != '\n') pos++; *pos = '\0'; os_strlcpy(addr, buf, addr_len); return 0; }
static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print) { #ifdef ANDROID char buf[4096]; #else char buf[2048]; #endif size_t len; int ret; if (ctrl_conn == NULL) { printf("Not connected to wpa_supplicant - command dropped.\n"); return -1; } len = sizeof(buf) - 1; ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, wpa_cli_msg_cb); if (ret == -2) { printf("'%s' command timed out.\n", cmd); return -2; } else if (ret < 0) { printf("'%s' command failed.\n", cmd); return -1; } if (print) { buf[len] = '\0'; printf("%s", buf); } return 0; }
void SIGQUIT_handler(int sig) { char *cmd = "GET channel"; char buf[2]; size_t len; int ret; int ShmID_getchar; char *ShmPTR_getchar; key_t MyKey_getchar; MyKey_getchar = 7878; ShmID_getchar = shmget(MyKey_getchar, sizeof(char), IPC_CREAT | 0666); ShmPTR_getchar = (char *) shmat(ShmID_getchar, NULL, 0); if(sig == SIGQUIT) { printf("SIGQUIT signal to get channel received\n"); } ctrl_ifname = "wlan0"; len = sizeof(buf)-1; ctrl_conn = hostapd_cli_open_connection(ctrl_ifname); if (ctrl_conn) { printf("Connection established.\n"); } ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, &len, hostapd_cli_msg_cb); printf("GET channel command sent\n"); printf("Channel in received buffer is: %c\n", buf[0]); //Sharring channel with http server *ShmPTR_getchar = buf[0]; signal(sig, SIGQUIT_handler); }
static void hostapd_cli_action(struct wpa_ctrl *ctrl) { fd_set rfds; int fd, res; struct timeval tv; char buf[256]; size_t len; fd = wpa_ctrl_get_fd(ctrl); while (!hostapd_cli_quit) { FD_ZERO(&rfds); FD_SET(fd, &rfds); tv.tv_sec = ping_interval; tv.tv_usec = 0; res = select(fd + 1, &rfds, NULL, NULL, &tv); if (res < 0 && errno != EINTR) { perror("select"); break; } if (FD_ISSET(fd, &rfds)) hostapd_cli_recv_pending(ctrl, 0, 1); else { len = sizeof(buf) - 1; if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len, hostapd_cli_action_process) < 0 || len < 4 || os_memcmp(buf, "PONG", 4) != 0) { printf("hostapd did not reply to PING " "command - exiting\n"); break; } } } }
int wifi_send_command(struct wpa_ctrl *ctrl, const char *cmd, char *reply, size_t *reply_len) { int ret; if (ctrl_conn == NULL) { LOGV("Not connected to wpa_supplicant - \"%s\" command dropped.\n", cmd); return -1; } if (strcmp(cmd, "DRIVER START") == 0) { LOGD("wifi.c : load driver after resume\n"); wifi_load_driver(); } ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), reply, reply_len, NULL); LOGV("wifi.c : cmd=%s, reply=%s\n", cmd, reply); if (strcmp(cmd, "DRIVER STOP") == 0) { LOGD("wifi.c : unload driver before suspend\n"); wifi_unload_driver(); } if (ret == -2) { LOGD("'%s' command timed out.\n", cmd); /* unblocks the monitor receive socket for termination */ write(exit_sockets[0], "T", 1); return -2; } else if (ret < 0 || strncmp(reply, "FAIL", 4) == 0) { return -1; } if (strncmp(cmd, "PING", 4) == 0) { reply[*reply_len] = '\0'; } return 0; }
/* wpatalk_recv_pending -- process pending packets from authentication * daemon, and return > 0 if there are more packets (less than zero * if error). * If block is set to 1, will sleep waiting for up to one packet. */ static int wpatalk_recv_pending(int block) { struct pollfd fds[1]; int nfds; int more = 0; int timeout_msec = 0; /* negative for infinity */ char buf[512]; /* note: large enough to fit in unsolicited messages */ size_t len; int nloops; for (nloops = 0; ; nloops++) { if (ctrl_conn == NULL) { return -1; } fds[0].fd = wpa_ctrl_get_fd(ctrl_conn); fds[0].events = POLLIN; fds[0].revents = 0; nfds = 1; if (nloops > 0) timeout_msec = 1000; else timeout_msec = 0; nfds = poll(fds, nfds, timeout_msec); if (nfds < 0) { if (errno == EINTR) continue; #if 1 wpatalk_error("Connection to daemon lost"); #else wpatalk_fatal("Died on poll() error %d", errno); #endif return -1; } more = (nfds > 0); if (more == 0) { if (block == 0) { return 0; /* nothing pending */ } else { /* blocking mode */ /* verify that connection is still working */ size_t len = sizeof(buf) - 1; if (wpa_ctrl_request(ctrl_conn, "PING", 4, buf, &len, wpatalk_action_cb) < 0 || len < 4 || os_memcmp(buf, "PONG", 4) != 0) { wpatalk_error("daemon did not reply to PING"); return -1; } /* and try again */ continue; } } len = sizeof(buf) - 1; if (wpa_ctrl_recv(ctrl_conn, buf, &len) == 0) { buf[len] = '\0'; wpatalk_info("GOT: %s", buf); wpatalk_action_process(buf); } else { wpatalk_error("Could not read pending message."); } break; } return more; }
static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd, int print) { char buf[4096]; size_t len; int ret; if (ctrl_conn == NULL) { printf("Not connected to hostapd - command dropped.\n"); return -1; } len = sizeof(buf) - 1; ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, hostapd_cli_msg_cb); if (ret == -2) { printf("'%s' command timed out.\n", cmd); return -2; } else if (ret < 0) { printf("'%s' command failed.\n", cmd); return -1; } if (print) { buf[len] = '\0'; printf("%s", buf); } return 0; }
void AddInterface::interfaceSelected(QTreeWidgetItem *sel) { if (!sel) return; #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE struct wpa_ctrl *ctrl; int ret; char buf[20], cmd[256]; size_t len; /* * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB * <driver_param>TAB<bridge_name> */ snprintf(cmd, sizeof(cmd), "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s", sel->text(1).toAscii().constData(), "default", sel->text(0).toAscii().constData(), "yes", "", ""); cmd[sizeof(cmd) - 1] = '\0'; ctrl = wpa_ctrl_open(NULL); if (ctrl == NULL) return; len = sizeof(buf) - 1; ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL); wpa_ctrl_close(ctrl); if (ret < 0) { QMessageBox::warning(this, "wpa_gui", tr("Add interface command could not be " "completed.")); return; } buf[len] = '\0'; if (buf[0] != 'O' || buf[1] != 'K') { QMessageBox::warning(this, "wpa_gui", tr("Failed to add the interface.")); return; } #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ #ifdef CONFIG_NATIVE_WINDOWS if (!addRegistryInterface(sel->text(1))) { QMessageBox::information(this, "wpa_gui", tr("Failed to add the interface into " "registry.")); } #endif /* CONFIG_NATIVE_WINDOWS */ wpagui->selectAdapter(sel->text(1)); close(); }
void SIGINT_handler(int sig) { char *cmd = "CHAN_SWITCH 5 "; char *finalCmd, charFreq[5]; char buf[2]; size_t len; int ret; int freq; if(sig == SIGINT) { printf("SIGINT signal to switch channel received\n"); } //get channel from http server key_t MyKey_chShare; int ShmID_chShare; char *ShmPTR_chShare; MyKey_chShare = 5555; if ((ShmID_chShare = shmget(MyKey_chShare, sizeof(char), 0666)) < 0) { perror("shmget"); exit(1); } ShmPTR_chShare = (char *) shmat(ShmID_chShare, NULL, 0); printf("Channel received from http server is %s\n", ShmPTR_chShare); //calculate the frequency to set in the channel switch command int channel; if(ShmPTR_chShare[0] == '0') { freq = 2412 + 5*((int)(ShmPTR_chShare[1]) - '1'); } else { sscanf(ShmPTR_chShare, "%d", &channel); freq = 2412 + 5*(channel-1); } snprintf(charFreq, sizeof charFreq, "%d", freq); //generate command for channel switch finalCmd = malloc(strlen(cmd)+1); strcpy(finalCmd, cmd); strcat(finalCmd, charFreq); printf("Switch channel command = %s\n", finalCmd); ctrl_ifname = "wlan0"; len = sizeof(buf)-1; ctrl_conn = hostapd_cli_open_connection(ctrl_ifname); if (ctrl_conn) { printf("Connection established.\n"); } printf("command generated = %s\n", finalCmd); ret = wpa_ctrl_request(ctrl_conn, finalCmd, strlen(finalCmd), buf, &len, hostapd_cli_msg_cb); printf("switch channel command sent\n"); signal(sig, SIGINT_handler); }
bool wifi_manager::save_wificonfig() { bool ret = false; size_t len = WIFI_BUFFER_LEN - 1; do { if(wpa_ctrl_request(_ctrl,"SAVE_CONFIG",sizeof("SAVE_CONFIG"),_buffer,&len,NULL)) break; ret = true; }while(0); return ret; }
static int wpa_ctrl_attach_helper(struct wpa_ctrl *ctrl, int attach) { char buf[10]; int ret; size_t len = 10; ret = wpa_ctrl_request(ctrl, attach ? "ATTACH" : "DETACH", 6, buf, &len, NULL); if (ret < 0) return ret; if (len == 3 && os_memcmp(buf, "OK\n", 3) == 0) return 0; return -1; }
int WiFiNode::makeRequest(const char *cmd, char *reply, size_t *replyLen) { if (!wpaCtrl || !cmd || !reply || !replyLen) { DBGMSG_ERR("Input is Null"); return -1; } int res = wpa_ctrl_request(wpaCtrl, cmd, strlen(cmd), reply, replyLen, NULL); reply[*replyLen] = '\0'; DBGMSG_M("Req [%s] reply [%d] Reply: \n%s", cmd, *replyLen, reply); if (res || !replyLen) { DBGMSG_ERR("Req failed"); } return res; }
int WpaGui::ctrlRequest(const char *cmd, char *buf, size_t *buflen) { int ret; if (ctrl_conn == NULL) return -3; ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, buflen, NULL); if (ret == -2) printf("'%s' command timed out.\n", cmd); else if (ret < 0) printf("'%s' command failed.\n", cmd); return ret; }
bool wifi_manager::addWifiNetwork(const char* ssid,const char* passwd) { bool ret = false; size_t len = WIFI_BUFFER_LEN - 1; char buf[256] = {0}; int id; char* p; do { if(wpa_ctrl_request(_ctrl,"ADD_NETWORK",sizeof("ADD_NETWORK"),_buffer,&len,NULL)) break; _buffer[len] = 0; p = _buffer; while(*p != '\n')p++; *p = 0; id = parse_int_dec(_buffer); //printf("new network id:%s\n",_buffer); sprintf(buf,"SET_NETWORK %d ssid \"%s\"",id,ssid); if(wpa_ctrl_request(_ctrl,buf,strlen(buf),_buffer,&len,NULL)) break; printf("%s\n",buf); sprintf(buf,"SET_NETWORK %d psk \"%s\"",id,passwd); if(wpa_ctrl_request(_ctrl,buf,strlen(buf),_buffer,&len,NULL)) break; _buffer[len] = 0; //printf("%s\n%s",buf,_buffer); ret = true; }while(0); return ret; }
int WpaGui::ctrlRequest(const char *cmd, char *buf, size_t *buflen) { int ret;printf("This is WpaGui::ctrlRequest Function.And the cmd is %s \n",cmd); if (ctrl_conn == NULL) return -3; ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, buflen, wpa_gui_msg_cb); if (ret == -2) printf("'%s' command timed out.\n", cmd); else if (ret < 0) printf("'%s' command failed.\n", cmd); return ret; }
static int netcfg_wpa_cmd (char *cmd) { char buf[256]; size_t len; int ret; len = sizeof(buf) -1; ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL); if (ret < 0) { di_info("Sending %s to wpasupplicant failed", cmd); return 1; } return 0; }
bool wifi_manager::connectWifi(int id) { bool ret = false; size_t len = WIFI_BUFFER_LEN - 1; char buf[64] = {0}; do { sprintf(buf,"SELECT_NETWORK %d",id); if(wpa_ctrl_request(_ctrl,buf,strlen(buf),_buffer,&len,NULL)) break; //printf("%s\n",buf); ret = true; }while(0); return ret; }
int get_wpa_status(const char *ifname, const char *field, char *obuf, size_t obuf_size) { struct wpa_ctrl *ctrl; char buf[4096]; char *pos, *end; size_t len, flen; ctrl = wpa_open_ctrl(ifname); if (ctrl == NULL) return -1; len = sizeof(buf); if (wpa_ctrl_request(ctrl, "STATUS", 6, buf, &len, NULL) < 0) { wpa_ctrl_close(ctrl); return -1; } wpa_ctrl_close(ctrl); buf[len] = '\0'; flen = strlen(field); pos = buf; while (pos + flen < buf + len) { if (pos > buf) { if (*pos != '\n') { pos++; continue; } pos++; } if (strncmp(pos, field, flen) != 0 || pos[flen] != '=') { pos++; continue; } pos += flen + 1; end = strchr(pos, '\n'); if (end == NULL) return -1; *end++ = '\0'; if (end - pos > (int) obuf_size) return -1; memcpy(obuf, pos, end - pos); return 0; } return -1; }
int sup_cmd(char *result, char *cmd,...) { va_list args; int res; char cmdbuf [256]; size_t replen = 512; if (!wpa_client) return -1; /* Not attached to wpa_supplicant control interface. */ va_start(args, cmd); vsnprintf(cmdbuf, 256, cmd, args); va_end(args); res = wpa_ctrl_request(wpa_client, cmdbuf, strlen(cmdbuf), result, &replen, wpa_unsolicited); if (res) return res; }
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path) { struct wpa_ctrl *ctrl; char buf[128]; size_t len; ctrl = os_malloc(sizeof(*ctrl)); if (ctrl == NULL) return NULL; os_memset(ctrl, 0, sizeof(*ctrl)); ctrl->s = socket(PF_INET, SOCK_DGRAM, 0); if (ctrl->s < 0) { perror("socket"); os_free(ctrl); return NULL; } ctrl->local.sin_family = AF_INET; ctrl->local.sin_addr.s_addr = htonl((127 << 24) | 1); if (bind(ctrl->s, (struct sockaddr *) &ctrl->local, sizeof(ctrl->local)) < 0) { close(ctrl->s); os_free(ctrl); return NULL; } ctrl->dest.sin_family = AF_INET; ctrl->dest.sin_addr.s_addr = htonl((127 << 24) | 1); ctrl->dest.sin_port = htons(WPA_CTRL_IFACE_PORT); if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest, sizeof(ctrl->dest)) < 0) { perror("connect"); close(ctrl->s); os_free(ctrl); return NULL; } len = sizeof(buf) - 1; if (wpa_ctrl_request(ctrl, "GET_COOKIE", 10, buf, &len, NULL) == 0) { buf[len] = '\0'; ctrl->cookie = strdup(buf); } return ctrl; }
static int wpa_set_psk(char *passphrase) { int ret, res; size_t len; char buf[256]; char cmd[256]; res = snprintf(cmd, sizeof(cmd), "SET_NETWORK 0 %s \"%s\"", "psk", passphrase); if (res < 0) return 1; len = sizeof(buf) -1; ret = wpa_ctrl_request(ctrl, cmd, sizeof(cmd), buf, &len, NULL); if (ret != 0) return 1; return 0; }
void AddInterface::addInterfaces() { #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE struct wpa_ctrl *ctrl; int ret; char buf[2048]; size_t len; ctrl = wpa_ctrl_open(NULL); if (ctrl == NULL) return; len = sizeof(buf) - 1; ret = wpa_ctrl_request(ctrl, "INTERFACE_LIST", 14, buf, &len, NULL); if (ret < 0) { wpa_ctrl_close(ctrl); return; } buf[len] = '\0'; wpa_ctrl_close(ctrl); QString ifaces(buf); QStringList lines = ifaces.split(QRegExp("\\n")); for (QStringList::Iterator it = lines.begin(); it != lines.end(); it++) { QStringList arg = (*it).split(QChar('\t')); if (arg.size() < 3) continue; QTreeWidgetItem *item = new QTreeWidgetItem(interfaceWidget); if (!item) break; item->setText(0, arg[0]); item->setText(1, arg[1]); item->setText(2, arg[2]); } interfaceWidget->resizeColumnToContents(0); interfaceWidget->resizeColumnToContents(1); interfaceWidget->resizeColumnToContents(2); #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ }
static int wpa_set_ssid (char *ssid) { int ret, res; size_t len; char cmd[256]; char buf[256]; res = snprintf(cmd, sizeof(cmd), "SET_NETWORK 0 %s \"%s\"", "ssid", ssid); if (res < 0) return 1; len = sizeof(buf) -1; ret = wpa_ctrl_request(ctrl, cmd, sizeof(cmd), buf, &len, NULL); if (ret != 0) { di_info("Failed to set the ssid with wpasupplicant"); return 1; } return 0; }
int wifi_send_command(struct wpa_ctrl *ctrl, const char *cmd, char *reply, size_t *reply_len) { int ret; if (ctrl_conn == NULL) { LOGV("Not connected to wpa_supplicant - \"%s\" command dropped.\n", cmd); return -1; } ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), reply, reply_len, NULL); if (ret == -2) { LOGD("'%s' command timed out.\n", cmd); return -2; } else if (ret < 0 || strncmp(reply, "FAIL", 4) == 0) { return -1; } if (strncmp(cmd, "PING", 4) == 0) { reply[*reply_len] = '\0'; } return 0; }
int wpa_command_resp(const char *ifname, const char *cmd, char *resp, size_t resp_size) { struct wpa_ctrl *ctrl; size_t len; printf("wpa_command(ifname='%s', cmd='%s')\n", ifname, cmd); ctrl = wpa_open_ctrl(ifname); if (ctrl == NULL) return -1; len = resp_size; if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), resp, &len, NULL) < 0) { printf("wpa_command: wpa_ctrl_request failed\n"); wpa_ctrl_close(ctrl); return -1; } wpa_ctrl_close(ctrl); resp[len] = '\0'; return 0; }
static void wpa_cli_action(struct wpa_ctrl *ctrl) { #ifdef CONFIG_ANSI_C_EXTRA /* TODO: ANSI C version(?) */ printf("Action processing not supported in ANSI C build.\n"); #else /* CONFIG_ANSI_C_EXTRA */ fd_set rfds; int fd, res; struct timeval tv; char buf[256]; /* note: large enough to fit in unsolicited messages */ size_t len; fd = wpa_ctrl_get_fd(ctrl); while (!wpa_cli_quit) { FD_ZERO(&rfds); FD_SET(fd, &rfds); tv.tv_sec = 2; tv.tv_usec = 0; res = select(fd + 1, &rfds, NULL, NULL, &tv); if (res < 0 && errno != EINTR) { perror("select"); break; } if (FD_ISSET(fd, &rfds)) wpa_cli_recv_pending(ctrl, 0, 1); else { /* verify that connection is still working */ len = sizeof(buf) - 1; if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len, wpa_cli_action_cb) < 0 || len < 4 || os_memcmp(buf, "PONG", 4) != 0) { printf("wpa_supplicant did not reply to PING " "command - exiting\n"); break; } } } #endif /* CONFIG_ANSI_C_EXTRA */ }