Ejemplo n.º 1
0
int transportMgr::sendMessage(WiFiClient socket,String sendBuf)
{

	char bufHeader[20];
	long length=sendBuf.length();
	sprintf(bufHeader,"%s%08d",PACKET_MAGIC,length);
	socket.print(bufHeader);
	Serial.println(bufHeader);

	for(int split=0; split< length ; split+=STR_LENGTH_SPLIT)
	{
		if(length-split < STR_LENGTH_SPLIT)	
 		{
 			socket.print(sendBuf.substring(split));
			Serial.println(sendBuf.substring(split));
 			
 		}
 		else
 		{
 			socket.print(sendBuf.substring(split,split+STR_LENGTH_SPLIT));
			Serial.println(sendBuf.substring(split,split+STR_LENGTH_SPLIT));
 		}
	}

	Serial.println(sendBuf);

	return 0;
}
Ejemplo n.º 2
0
void Farmy::sendData(const char* device_id, String api_key, WiFiClient client, String data)
{
  // Todo: use retry to connect internet.
  Serial.println("Connected to Famry.");
  Serial.println("Posted:" + data);

  // Create HTTP POST Data
  String url = String("/api/v0/user_devices/") + device_id + "/sensor_datas/";
  client.print(String("POST ") + url + " HTTP/1.1\n"+ "Host: " + host + "\n");
  client.print(String("Host: ") + host + "\n");
  client.print("Content-Type: application/json\n");
  client.print(String("X-Farmy-Api-Key: ") + api_key + "\n");
  client.print("Content-Length: ");
  client.print(data.length());
  client.print("\n\n");

  client.print(data);
  Serial.println("Posted finished -----------");

  delay(500);
  if (!client.connected()) {
      Serial.println();
      Serial.println("disconnecting.");
      client.stop();
  }
}
Ejemplo n.º 3
0
void EncodeNSendMessage::SendJSONstatusEvent(WiFiClient localclient, String MacAddr, HomeNodeDDI Hnode)
{
	gsBufferWiFi="";
	gsBufferWiFi+='{';  
	SendJSONobject("Job", "Event", false);
	SendJSONobject("NodeID", (char *)MacAddr.c_str(), false);  
	gsBufferWiFi+="\"Status\":[";
	localclient.print(gsBufferWiFi.c_str());	  

	{
		int i;
		//JSONstatus1  // Presence
		gsBufferWiFi="";
		for(i = 0 ; i < strlen(JSONstatus1) ; i++) 
		{
			gsBufferWiFi+=(char)pgm_read_byte_near(JSONstatus1 + i);
		}
		if(Hnode.proximity <= 50)	// door open
		{ 
			gsBufferWiFi+="Mail";
		}
		else
		{ 
			gsBufferWiFi+="Empty"; 	 
		}

		gsBufferWiFi+="\"}";
		localclient.print(gsBufferWiFi.c_str());
	}
	localclient.print("]}\n");
}
// See if port 80 is accessable.  Try 8080 as well.
boolean WiFiManager::attemptClient(const char *szUrl)
{
  WiFiClient client;

  int i;
  Serial.print("Probe port 80");
  for(i = 0; i < 5; i++)
  {
    if (client.connect(szUrl, httpPort)) {
      client.stop();
      Serial.println("Port 80 success");
      return true;
    }
    Serial.print(".");
    delay(20);
  }
  httpPort = 8080;
  Serial.println("");
  Serial.print("Probe port 8080");
  for(i = 0; i < 5; i++)
  {
    if (client.connect(szUrl, httpPort)) {
      client.stop();
      Serial.println("Port 8080 success");
      return true;
    }
    Serial.print(".");
    delay(20);
  }
  Serial.println("");
  Serial.println("No joy");
  return false;  
}
Ejemplo n.º 5
0
/********************************************************************
  connect establishes a connection to the Slack RTM API


********************************************************************/
bool ArduinoSlackBot::connect() {
  // Step 1: Find WebSocket address via RTM API (https://api.slack.com/methods/rtm.start)
  HTTPClient http;
  String slackAddr = "https://slack.com/api/rtm.start?token="; 
  slackAddr = String(slackAddr + slackToken);
  PRINTLN(slackAddr);

  http.begin(slackAddr.c_str(), slackSSLFingerprint);
  int httpCode = http.GET();

  if (httpCode != HTTP_CODE_OK) {
    PRINTF("HTTP GET failed with code %d\n", httpCode);
    return false;
  }

  WiFiClient *client = http.getStreamPtr();
  client->find("wss:\\/\\/");
  String host = client->readStringUntil('\\');
  String path = client->readStringUntil('"');
  path.replace("\\/", "/");

  // Step 2: Open WebSocket connection and register event handler
  PRINTLN("WebSocket Host=" + host + " Path=" + path);
  webSocket.beginSSL(host, 443, path, "", "");
  webSocket.onEvent(webSocketEvent);
  return true;
}
Ejemplo n.º 6
0
String DHwifi::HttpRequest( String req )
{
  WiFiClient client;

  char host[99];
  m_remoteServer.toCharArray( host, 99);
  const int httpPort = 80;

  if (!client.connect(host, httpPort))
  {
    Serial.print( host );
    Serial.println(" connection failed");
    return "";
  }

  client.print(String("GET ") + req + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");

  delay(10);

  String result;
  // Read all the lines of the reply from server and print them to Serial
  while (client.available())
  {
    result = client.readStringUntil('\r');
  }
  return result;
}
Ejemplo n.º 7
0
String Iotfy_getdata(int no_of_bytes, int timeout)
{
  int ctr=0;
  int pt=millis()/1000;
  String data="";
  data.reserve(no_of_bytes);
  while(1)
  {
    if(client.available())
    {
      char c=client.read();
      data+=c;
      Serial.print(c);
      ctr++;
      if(ctr==no_of_bytes)
        break;
    }      
    else
    {
      if(millis()/1000-pt>timeout)
      {
        pt=millis()/1000;
        break;    
      } 
    }
  }
  Serial.println("calling disconnect");
  client.flush();
  client.stop();
     
  return data;
}
Ejemplo n.º 8
0
void EIoTCloudRestApi::sendParameter(const char * instaceParamId, String value)
{
  WiFiClient client;
   
  while(!client.connect(EIOT_CLOUD_ADDRESS, EIOT_CLOUD_PORT)) {
    debug("connection failed");
	wifiConnect(); 
  }

  String url = "";
  // URL: /RestApi/SetParameter/[instance id]/[parameter id]/[value]
  url += "/RestApi/SetParameter/" + String(instaceParamId) + "/" + value; // generate EasIoT cloud update parameter URL

  debug("POST data to URL: ");
#ifdef DEBUG
  char buff[300];
  url.toCharArray(buff, 300);
  debug(buff);
#endif
  
  client.print(String("POST ") + url + " HTTP/1.1\r\n" +
               "Host: " + String(EIOT_CLOUD_ADDRESS) + "\r\n" + 
               "Connection: close\r\n" + 
               "Content-Length: 0\r\n" + 
               "\r\n");

  delay(100);
  while(client.available()){
#ifdef DEBUG
  String line = client.readStringUntil('\r');
  line.toCharArray(buff, 300);
  debug(buff);
#endif
  }
}
Ejemplo n.º 9
0
int transportMgr::sendMessage(WiFiClient socket,JsonObject&  sendMsg)
{
#if 0
	long length=0;
	String header=String(PACKET_MAGIC);
	length=sendMsg.printTo(Serial);
	if(length>999)		header=header+length;
	else if(length>99)	header=header+"0"+length;
	else if(length>9)	header=header+"00"+length;
	else 				header=header+"000"+length;
	socket.print(header);
	sendMsg.printTo(socket);
	sendMsg.printTo(Serial);
	//Serial.println(".....................");
	
#else
	char bufHeader[20];
	long length=sendMsg.printTo(Serial);
	sprintf(bufHeader,"%s%08d",PACKET_MAGIC,length);
	socket.print(bufHeader);
	sendMsg.printTo(socket);
	Serial.println("sent!");
	//socket.print("{\"messageType\":\"configuableTime\",\"configuableType\":\"light\",\"time\":\"40\"}\n");
	//Serial.println("sent!!");
	
	
#endif
}
Ejemplo n.º 10
0
void WiFiClient::stopAllExcept(WiFiClient* except) 
{
    for (WiFiClient* it = _s_first; it; it = it->_next) {
        if (it != except) {
            it->stop();
        }
    }
}
Ejemplo n.º 11
0
uint8_t ESP8266WebServer::_uploadReadByte(WiFiClient& client){
  int res = client.read();
  if(res == -1){
    while(!client.available() && client.connected())
      yield();
    res = client.read();
  }
  return (uint8_t)res;
}
Ejemplo n.º 12
0
void loop() {

	static boolean packetActive = false;
	static uint8_t index = 0;
	static boolean readingReturn = false;
	static uint8_t rindex = 0;

	if (!client.connected()) {
		// try to connect to a new client
		client = server.available();
	} else {
		// read data from the connected client
		if (client.available() > 0) {
			char c = client.read();

			if (packetActive) {
				commandBuffer[index] = c;
				commandBuffer[++index] = 0;
				if (c == EOP) {
					comHandler();
					packetActive = false;
				}
			}

			else if (c == SOP) {
				index = 0;
				commandBuffer[index] = c;
				commandBuffer[++index] = 0;
				packetActive = true;
			}

			if (returnReady) {
				client.println(returnBuffer);
				server.println(returnBuffer);
				Serial.println(returnBuffer);
				returnReady = false;
			}
		}
	}

	if (Serial.available() && !returnReady) {
		char s = Serial.read();

		if (s == SOP) {
			readingReturn = true;
			rindex = 0;
		}
		if (readingReturn) {
			returnBuffer[rindex] = s;
			returnBuffer[++rindex] = 0;

			if (s == EOP) {
				returnReady = true;
			}
		}
	}
}
Ejemplo n.º 13
0
void transmitTele()
{
  Serial.println("tele"); 
  
  while(!alreadyConnectedTele)
  {
    //attempt to save a client connecting to the server
    teleClient = teleServer.available();
    
    //if a client is connected, begin communication
    if (teleClient) {
      if (!alreadyConnectedTele) {
        // clead out the input buffer:
        teleClient.flush();
        Serial.println("We have a new client");
        alreadyConnectedTele = true;
        
      }
    }
  }
  
    for(int i = 0; i < 20; i++)
    {
      if (teleClient.available() > 0) {
        // read the bytes incoming from the client:
        char thisChar = teleClient.read();
        // echo the bytes back to the client:
        
        if(thisChar == '1')
          teleServer.println(curSpeedKn * KNOTS_TO_MPS);
          
        if(thisChar == '2')  
          teleServer.println(pollPing());
          
        if(thisChar == '3')
          teleServer.println(distToTar());
          
        if(thisChar == '4')
          teleServer.println(curLat);
        
        if(thisChar == '5')
          teleServer.println(curLon);
        
        if(thisChar == '6')
          teleServer.println(curHead);
        
        
        // echo the bytes to the server as well:
        Serial.println(thisChar);
      }
    }
    
    
    
  
}
Ejemplo n.º 14
0
void Con::TCPhandler(){
   if (this->curType&CON_TCP){
      if (ConSrv.hasClient()){
         if (ConTcp.connected()){
            ConTcp.stop();
         }
         ConTcp=ConSrv.available();
         ConTcp.write("Hello\n",6);
      }  
   }
}
Ejemplo n.º 15
0
/**
 * Wait for a WiFiClient to connect
 *
 * @returns: True if the client is ready, false otherwise.
 * 
 */
bool ESP8266WiFiMesh::waitForClient(WiFiClient curr_client, int max_wait)
{
	int wait = max_wait;
	while(curr_client.connected() && !curr_client.available() && wait--)
		delay(3);

	/* Return false if the client isn't ready to communicate */
	if (WiFi.status() == WL_DISCONNECTED || !curr_client.connected())
		return false;
	
	return true;
}
Ejemplo n.º 16
0
void connectClients() {
	if (server.hasClient()) {
		if (!serverClient || !serverClient.connected()) {
			if (serverClient) serverClient.stop();
			serverClient = server.available();
		} else {
			//no free/disconnected spot so reject
			WiFiClient rejectClient = server.available();
			rejectClient.stop();
		}
	}
}
Ejemplo n.º 17
0
void loop() {
  // check the network connection once every 10 seconds:
  delay(10000);
  printCurrentNet();

  // Trying to connect to http://hasthelargehadroncolliderdestroyedtheworldyet.com/
  Serial5.println("Trying to connect to : www.hasthelargehadroncolliderdestroyedtheworldyet.com :");
  httpRequest();
  while( client.available() )
  {
    Serial5.print((char)(client.read()));
  }
  Serial5.println("END");
}
Ejemplo n.º 18
0
extern "C" void MW_WifiTCPFinalread(uint8_t wifitcpindex, uint8_t *data, uint32_t serverport, int32_t *outStatus)
{
    int libFcnOutput;
    WiFiClient client = server[wifitcpindex].available();
    if (client == true) {
        libFcnOutput = client.read();
        *data = (uint8_t) libFcnOutput;
        *outStatus = (libFcnOutput != -1);
    }

    else
    {
        //When the client is not connected the status flag is accordingly toggled. 
        *outStatus = 0;
    }
}
Ejemplo n.º 19
0
AJ_Status AJ_Net_Connect(AJ_NetSocket* netSock, uint16_t port, uint8_t addrType, const uint32_t* addr)
{
    int ret;

    IPAddress ip(*addr);

    AJ_InfoPrintf(("AJ_Net_Connect(nexSock=0x%p, port=%d., addrType=%d., addr=0x%p)\n", netSock, port, addrType, addr));

    AJ_InfoPrintf(("AJ_Net_Connect(): Connect to 0x%x:%u.\n", addr, port));;

    ret = g_client.connect(ip, port);

#ifdef NOTDEF
    Serial.print("Connecting to: ");
    Serial.print(ip);
    Serial.print(':');
    Serial.println(port);
#endif

    if (ret == -1) {
        AJ_ErrPrintf(("AJ_Net_Connect(): connect() failed: %d: status=AJ_ERR_CONNECT\n", ret));
        return AJ_ERR_CONNECT;
    } else {
        AJ_IOBufInit(&netSock->rx, rxData, sizeof(rxData), AJ_IO_BUF_RX, (void*)&g_client);
        netSock->rx.recv = AJ_Net_Recv;
        AJ_IOBufInit(&netSock->tx, txData, sizeof(txData), AJ_IO_BUF_TX, (void*)&g_client);
        netSock->tx.send = AJ_Net_Send;
        AJ_ErrPrintf(("AJ_Net_Connect(): connect() success: status=AJ_OK\n"));
        return AJ_OK;
    }
    AJ_ErrPrintf(("AJ_Net_Connect(): connect() failed: %d: status=AJ_ERR_CONNECT\n", ret));
    return AJ_ERR_CONNECT;
}
Ejemplo n.º 20
0
// FLRDDE626>APRS,qAS,EGHL:/074548h5111.32N/00102.04W'086/007/A=000607 id0ADDE626 -019fpm +0.0rot 5.5dB 3e -4.3kHz
void WiFi_forward_to_cloud() {
  tmElements_t tm;
  char str_lat[8];
  char str_lon[8];

  breakTime(fo.timestamp, tm);

  dtostrf_workaround(take_minutes(fo.latitude), 5, 2, str_lat);
  dtostrf_workaround(take_minutes(fo.longtitude), 5, 2, str_lon);

  //Serial.print(fo.latitude); Serial.print(" "); Serial.println(fo.longtitude); 

  snprintf(UDPpacketBuffer, sizeof(UDPpacketBuffer), \
    "FLR%X>APRS,qAS,%s:/%02d%02d%02dh%02d%s%s/%03d%s%s/A=%05u TS:%d RAW:%s", \
    fo.addr, STATION_ID, tm.Hour, tm.Minute, tm.Second, \
    abs(take_degrees(fo.latitude)), str_lat, (fo.latitude < 0 ? "S" : "N"), \
    abs(take_degrees(fo.longtitude)), str_lon, (fo.longtitude < 0 ? "W" : "E"), \
    fo.altitude, fo.timestamp, fo.raw.c_str() );

#ifdef SERIAL_VERBOSE
  Serial.println(UDPpacketBuffer);
#endif

  client.println(UDPpacketBuffer);
}
Ejemplo n.º 21
0
/*
 *  ======== doCommand ========
 *  execute the command in buffer and send results to client
 */
static void doCommand(char *buffer, int len, WiFiClient client)
{
    if (buffer[1] == '\n' || buffer[1] == '\r') {
        doWASD(buffer[0], client);
    }
    else {
#if 0
        long int addr = 0;
        int cnt = 0;
        char *ptr;

        /* get the address and count from the command */
        getAddrCnt(buffer, len, &addr, &cnt);

        /* send client cnt bytes starting from addr */
        ptr = (char *)addr;
        while (cnt-- > 0) {
            int status;
            if ((status = client.write(*ptr)) != 1) {
                return;
            }
            ptr++;
        }
#else
        doWASD(' ', client);
#endif
    }
}
Ejemplo n.º 22
0
void loop() {
  String data;
	digitalWrite(LED_PIN, state);
	state = !state;
  if (client.connected()) {

    webSocketClient.getData(data);
    if (data.length() > 0) {
      Serial.print("Received data: ");
      Serial.println(data);
    }

    // capture the value of analog 1, send it along
    pinMode(1, INPUT);
    data = String(analogRead(1));

    webSocketClient.sendData(data);

  } else {
    Serial.println("Client disconnected.");
    while (1) {
      // Hang on disconnect.
    }
  }

  // wait to fully let the client disconnect
  delay(3000);

}
Ejemplo n.º 23
0
AJ_Status AJ_Net_Connect(AJ_BusAttachment* bus, const AJ_Service* service)
{
    int ret;
    IPAddress ip(service->ipv4);

    if (!(service->addrTypes & AJ_ADDR_TCP4)) {
        AJ_ErrPrintf(("AJ_Net_Connect(): only IPV4 TCP supported\n", ret));
        return AJ_ERR_CONNECT;
    }


    AJ_InfoPrintf(("AJ_Net_Connect(bus=0x%p, addrType=%d.)\n", bus, service->addrTypes));

    ret = g_client.connect(ip, service->ipv4port);


    if (ret != 1) {
        AJ_ErrPrintf(("AJ_Net_Connect(): connect() failed: %d: status=AJ_ERR_CONNECT\n", ret));
        return AJ_ERR_CONNECT;
    } else {
        AJ_IOBufInit(&bus->sock.rx, rxData, sizeof(rxData), AJ_IO_BUF_RX, (void*)&g_client);
        bus->sock.rx.recv = AJ_Net_Recv;
        AJ_IOBufInit(&bus->sock.tx, txData, sizeof(txData), AJ_IO_BUF_TX, (void*)&g_client);
        bus->sock.tx.send = AJ_Net_Send;
        AJ_ErrPrintf(("AJ_Net_Connect(): connect() success: status=AJ_OK\n"));
        return AJ_OK;
    }
    AJ_ErrPrintf(("AJ_Net_Connect(): connect() failed: %d: status=AJ_ERR_CONNECT\n", ret));
    return AJ_ERR_CONNECT;
}
//****************** Recieve data for ModBusMaster ****************
void MgsModbus::MbmRun()
{
  //****************** Read from socket ****************
  while (MbmClient.available()) {
    MbmByteArray[MbmCounter] = MbmClient.read();
    if (MbmCounter > 4)  {
      if (MbmCounter == MbmByteArray[5] + 5) { // the full answer is recieved  
        MbmClient.stop();
        MbmProcess();
        #ifdef DEBUG
          Serial.println("recieve klaar");
        #endif    
      }
    }
    MbmCounter++;
  }
}
Ejemplo n.º 25
0
/**
 * Send the supplied message then read back the other node's response
 * and pass that to the user-supplied handler.
 *
 * @target_ssid The name of the AP the other node has set up.
 * @message The string to send to the node.
 * @returns: True if the exchange was a succes, false otherwise.
 * 
 */
bool ESP8266WiFiMesh::exchangeInfo(String message, WiFiClient curr_client)
{
	curr_client.println( message.c_str() );

	if (!waitForClient(curr_client, 1000))
		return false;

	String response = curr_client.readStringUntil('\r');
	curr_client.readStringUntil('\n');

	if (response.length() <= 2) 
		return false;

	/* Pass data to user callback */
	_handler(response);
	return true;
}
Ejemplo n.º 26
0
void sync_led(WiFiClient client) {
  int new_brightness = -1;

  while (client.available()) {
    String line = client.readStringUntil('\r');

    int ix_magic_ld = line.indexOf("ld");
    int ix_colon = line.indexOf(":");

    if (ix_magic_ld != -1) {
      // Sync the LEDs
      int ix_led = line.substring(ix_magic_ld + 2, ix_colon).toInt();

      // The RGB value are encoded in Base 10 (not base 16) with "zero" padding.
      // LD<LED_INDEX>: FFFFFF
      // | |          | |
      // 0 2          C 2

      String hexval = line.substring(ix_colon + 2);

      long value = strtol(hexval.c_str(), NULL, 16);

      int led_r = value >> 16;
      int led_g = value >> 8 & 0xFF;
      int led_b = value & 0xFF;

      pixels.setPixelColor(ix_led, pixels.Color(led_r, led_g, led_b));
      pixels.show();
      #if DEBUG
      Serial.print("LED#");
      Serial.print(ix_led);
      Serial.print(" <rgb>:");
      Serial.print(led_r);
      Serial.print(',');
      Serial.print(led_g);
      Serial.print(',');
      Serial.print(led_b);
      Serial.print('\n');
      #endif
    }
    int ix_magic_br = line.indexOf("brightness");
    if (ix_magic_br != -1) {
      // Update the Brightness Values
      new_brightness = line.substring(ix_colon + 2).toInt();
    }
  }
Ejemplo n.º 27
0
void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
  
  debugClient.print("SSID: ");
  debugClient.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  debugClient.print("IP Address: ");
  debugClient.println(ip);

  // print the received signal strength:
  debugClient.print("signal strength (RSSI):");
  debugClient.print(rssi);
  debugClient.println(" dBm");
}
Ejemplo n.º 28
0
void RobotHostInterface::rcvCommand(struct HostCommand *command)
{
	byte rawCmd = 0xFF;
	WiFiClient client = robotServer->available();

	if (client) {
		Serial.print("Robot Client connected...");
		Serial.println("Waiting for a command......" );

		while (client.available() == 0 ) {
			delay( 100 );
		}

		rawCmd = (byte)client.read();
		Serial.print("Raw Command: ");
		Serial.print(rawCmd);

		command->cmd = rawCmd >> 3;
		command->arg = rawCmd & 0x07;

		Serial.print(", Cmd: ");
		Serial.print(command->cmd);
		Serial.print(", arg: ");
		Serial.println(command->arg);

		if (command->cmd == CMD_ARRIVAL || command->cmd == CMD_WATCHDOG) {
			if (command->cmd == CMD_ARRIVAL && getArrival()) {
				rawCmd = CMD_ARRIVAL << 3;
				setArrival(false);
			} else if (command->cmd == CMD_WATCHDOG) {
				rawCmd = 0xFF;
			} else {
				rawCmd = 0xFF;
			}
		}

		/* send acknowledgement */
		robotServer->write(rawCmd);

		delay(100);

		client.stop();
		Serial.println("Client Disconnected.\n");
	}
}
Ejemplo n.º 29
0
void Con::printf(const char *fmt, ...){
   int l;
   char buffer[255];

   l=strlen(fmt);
   va_list ap;
   va_start(ap, fmt);
   ets_vsnprintf(buffer,255, fmt, ap);
   va_end(ap);
   if (curType&CON_SERIAL){ 
      Serial.print(buffer);
   }
   if (this->curType&CON_TCP){ 
      if (ConTcp.connected()){
         ConTcp.print(buffer);
      }
   }
}
Ejemplo n.º 30
0
void loop() {
  // if there are incoming bytes available 
  // from the server, read them and print them:
  while (client.available()) {
    char c = client.read();
    Serial.write(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting from server.");
    client.stop();

    // do nothing forevermore:
    while(true);
  }
}