Beispiel #1
0
// Lua: server:listen( port, ip, function(con) )
// Lua: socket:connect( port, ip, function(con) )
static int net_start( lua_State* L, const char* mt )
{
  NODE_DBG("net_start is called.\n");
  struct espconn *pesp_conn = NULL;
  lnet_userdata *nud;
  unsigned port;
  size_t il;
  bool isserver = false;
  ip_addr_t ipaddr;
  const char *domain;
  uint8_t stack = 1;
  
  if (mt!=NULL && c_strcmp(mt, "net.server")==0)
    isserver = true;
  else if (mt!=NULL && c_strcmp(mt, "net.socket")==0)
    isserver = false;
  else
  {
    NODE_DBG("wrong metatable for net_start.\n");
    return 0;
  }
  nud = (lnet_userdata *)luaL_checkudata(L, stack, mt);
  luaL_argcheck(L, nud, stack, "Server/Socket expected");
  stack++;

  if(nud==NULL){
  	NODE_DBG("userdata is nil.\n");
  	return 0;
  }

  pesp_conn = nud->pesp_conn;
  port = luaL_checkinteger( L, stack );
  stack++;
  if( pesp_conn->type == ESPCONN_TCP )
  {
    if(isserver)
      pesp_conn->proto.tcp->local_port = port;
    else{
      pesp_conn->proto.tcp->remote_port = port;
      pesp_conn->proto.tcp->local_port = espconn_port();
    }
    NODE_DBG("TCP port is set: %d.\n", port);
  }
  else if (pesp_conn->type == ESPCONN_UDP)
  {
    if(isserver)
      pesp_conn->proto.udp->local_port = port;
    else{
      pesp_conn->proto.udp->remote_port = port;
      pesp_conn->proto.udp->local_port = espconn_port();
    }
    NODE_DBG("UDP port is set: %d.\n", port);
  }

  if( lua_isstring(L,stack) )   // deal with the domain string
  {
    domain = luaL_checklstring( L, stack, &il );
    stack++;
    if (domain == NULL)
    {
      if(isserver)
        domain = "0.0.0.0";
      else
        domain = "127.0.0.1";
    }
    ipaddr.addr = ipaddr_addr(domain);
    if( pesp_conn->type == ESPCONN_TCP )
    {
      if(isserver)
        c_memcpy(pesp_conn->proto.tcp->local_ip, &ipaddr.addr, 4);
      else
        c_memcpy(pesp_conn->proto.tcp->remote_ip, &ipaddr.addr, 4);
      NODE_DBG("TCP ip is set: ");
      NODE_DBG(IPSTR, IP2STR(&ipaddr.addr));
      NODE_DBG("\n");
    }
    else if (pesp_conn->type == ESPCONN_UDP)
    {
      if(isserver)
        c_memcpy(pesp_conn->proto.udp->local_ip, &ipaddr.addr, 4);
      else
        c_memcpy(pesp_conn->proto.udp->remote_ip, &ipaddr.addr, 4);
      NODE_DBG("UDP ip is set: ");
      NODE_DBG(IPSTR, IP2STR(&ipaddr.addr));
      NODE_DBG("\n");
    }
  }

  // call back function when a connection is obtained, tcp only
  if ( pesp_conn->type == ESPCONN_TCP ) {
    if (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION){
      lua_pushvalue(L, stack);  // copy argument (func) to the top of stack
      if(isserver)    // for tcp server connected callback
      {
        if(tcpserver_cb_connect_ref != LUA_NOREF)
          luaL_unref(L, LUA_REGISTRYINDEX, tcpserver_cb_connect_ref);
        tcpserver_cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX);
      } 
      else 
      {
        if(nud->cb_connect_ref != LUA_NOREF)
          luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_connect_ref);
        nud->cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX);
      }
    }
  }

  if(!isserver || pesp_conn->type == ESPCONN_UDP){    // self_ref is only needed by socket userdata, or udp server
  	lua_pushvalue(L, 1);  // copy to the top of stack
    if(nud->self_ref != LUA_NOREF)
      luaL_unref(L, LUA_REGISTRYINDEX, nud->self_ref);
  	nud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  }

  if( pesp_conn->type == ESPCONN_TCP )
  {
    if(isserver){   // no secure server support for now
      espconn_regist_connectcb(pesp_conn, net_server_connected);
      // tcp server, SSL is not supported
#ifdef CLIENT_SSL_ENABLE
      // if(nud->secure)
      //   espconn_secure_accept(pesp_conn);
      // else
#endif
        espconn_accept(pesp_conn);    // if it's a server, no need to dns.
        espconn_regist_time(pesp_conn, tcp_server_timeover, 0);
    }
    else{
      espconn_regist_connectcb(pesp_conn, net_socket_connected);
      espconn_regist_reconcb(pesp_conn, net_socket_reconnected);
#ifdef CLIENT_SSL_ENABLE
      if(nud->secure){
      	if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port)
          espconn_secure_disconnect(pesp_conn);
        // espconn_secure_connect(pesp_conn);
      }
      else
#endif
      {
      	if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port)
          espconn_disconnect(pesp_conn);
        // espconn_connect(pesp_conn);
      }
    }
  }
  else if (pesp_conn->type == ESPCONN_UDP)
  {
    espconn_regist_recvcb(pesp_conn, net_socket_received);
    espconn_regist_sentcb(pesp_conn, net_socket_sent);
  	if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port)
    	espconn_delete(pesp_conn);
    if(isserver)
      espconn_create(pesp_conn);    // if it's a server, no need to dns.
  }

  if(!isserver){
    if((ipaddr.addr == IPADDR_NONE) && (c_memcmp(domain,"255.255.255.255",16) != 0))
    {
      host_ip.addr = 0;
      dns_reconn_count = 0;
      if(ESPCONN_OK == espconn_gethostbyname(pesp_conn, domain, &host_ip, socket_dns_found)){
        socket_dns_found(domain, &host_ip, pesp_conn);  // ip is returned in host_ip.
      }
    }
    else
    {
      socket_connect(pesp_conn);
    }
  }
  return 0;  
}
Beispiel #2
0
// Lua: mqtt:connect( host, port, secure, auto_reconnect, function(client) )
static int mqtt_socket_connect( lua_State* L )
{
  NODE_DBG("enter mqtt_socket_connect.\n");
  lmqtt_userdata *mud = NULL;
  unsigned port = 1883;
  size_t il;
  ip_addr_t ipaddr;
  const char *domain;
  int stack = 1;
  unsigned secure = 0, auto_reconnect = 0;
  int top = lua_gettop(L);

  mud = (lmqtt_userdata *)luaL_checkudata(L, stack, "mqtt.socket");
  luaL_argcheck(L, mud, stack, "mqtt.socket expected");
  stack++;
  if(mud == NULL)
    return 0;

  if(mud->connected){
    return luaL_error(L, "already connected");
  }

  if(mud->pesp_conn){   //TODO: should I free tcp struct directly or ask user to call close()???
    mud->pesp_conn->reverse = NULL;
    if(mud->pesp_conn->proto.tcp)
      c_free(mud->pesp_conn->proto.tcp);
    mud->pesp_conn->proto.tcp = NULL;
    c_free(mud->pesp_conn);
    mud->pesp_conn = NULL;
  }

  struct espconn *pesp_conn = NULL;
	pesp_conn = mud->pesp_conn = (struct espconn *)c_zalloc(sizeof(struct espconn));
	if(!pesp_conn)
		return luaL_error(L, "not enough memory");

	pesp_conn->proto.udp = NULL;
	pesp_conn->proto.tcp = (esp_tcp *)c_zalloc(sizeof(esp_tcp));
	if(!pesp_conn->proto.tcp){
		c_free(pesp_conn);
		pesp_conn = mud->pesp_conn = NULL;
		return luaL_error(L, "not enough memory");
	}
	// reverse is for the callback function
	pesp_conn->reverse = mud;
	pesp_conn->type = ESPCONN_TCP;
	pesp_conn->state = ESPCONN_NONE;
  mud->connected = false;

  if( (stack<=top) && lua_isstring(L,stack) )   // deal with the domain string
  {
    domain = luaL_checklstring( L, stack, &il );

    stack++;
    if (domain == NULL)
    {
      domain = "127.0.0.1";
    }
    ipaddr.addr = ipaddr_addr(domain);
    c_memcpy(pesp_conn->proto.tcp->remote_ip, &ipaddr.addr, 4);
    NODE_DBG("TCP ip is set: ");
    NODE_DBG(IPSTR, IP2STR(&ipaddr.addr));
    NODE_DBG("\n");
  }

  if ( (stack<=top) && lua_isnumber(L, stack) )
  {
    port = lua_tointeger(L, stack);
    stack++;
    NODE_DBG("TCP port is set: %d.\n", port);
  }
  pesp_conn->proto.tcp->remote_port = port;
  pesp_conn->proto.tcp->local_port = espconn_port();
  mud->mqtt_state.port = port;

  if ( (stack<=top) && lua_isnumber(L, stack) )
  {
    secure = lua_tointeger(L, stack);
    stack++;
    if ( secure != 0 && secure != 1 ){
      secure = 0; // default to 0
    }
  } else {
    secure = 0; // default to 0
  }
  mud->secure = secure; // save

  if ( (stack<=top) && lua_isnumber(L, stack) )
  {
    auto_reconnect = lua_tointeger(L, stack);
    stack++;
    if ( auto_reconnect != 0 && auto_reconnect != 1 ){
      auto_reconnect = 0; // default to 0
    }
  } else {
    auto_reconnect = 0; // default to 0
  }
  mud->mqtt_state.auto_reconnect = auto_reconnect;

  // call back function when a connection is obtained, tcp only
  if ((stack<=top) && (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION)){
    lua_pushvalue(L, stack);  // copy argument (func) to the top of stack
    if(mud->cb_connect_ref != LUA_NOREF)
      luaL_unref(L, LUA_REGISTRYINDEX, mud->cb_connect_ref);
    mud->cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX);
    stack++;
  }

  lua_pushvalue(L, 1);  // copy userdata to the top of stack
  if(mud->self_ref != LUA_NOREF)
    luaL_unref(L, LUA_REGISTRYINDEX, mud->self_ref);
  mud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX);

  espconn_regist_connectcb(pesp_conn, mqtt_socket_connected);
  espconn_regist_reconcb(pesp_conn, mqtt_socket_reconnected);

  os_timer_disarm(&mud->mqttTimer);
  os_timer_setfn(&mud->mqttTimer, (os_timer_func_t *)mqtt_socket_timer, mud);
  // timer started in socket_connect()

  if((ipaddr.addr == IPADDR_NONE) && (c_memcmp(domain,"255.255.255.255",16) != 0))
  {
    host_ip.addr = 0;
    dns_reconn_count = 0;
    if(ESPCONN_OK == espconn_gethostbyname(pesp_conn, domain, &host_ip, socket_dns_found)){
      socket_dns_found(domain, &host_ip, pesp_conn);  // ip is returned in host_ip.
    }
  }
  else
  {
    socket_connect(pesp_conn);
  }

  NODE_DBG("leave mqtt_socket_connect.\n");
  return 0;
}