Просмотр исходного кода

Merge pull request #41 from SunXofRTT/master

添加/修正 http request
Bernard Xiong 7 лет назад
Родитель
Сommit
90f5f9a316

+ 938 - 0
rtthread-port/jerry_mqtt.c

@@ -0,0 +1,938 @@
+#include "jerry_mqtt.h"
+#include <rtdbg.h>
+
+static bool hasClient = false;
+
+void mqtt_event_callback(const void *args, uint32_t size)
+{
+    mqtt_cbinfo_t *cb_info = (mqtt_cbinfo_t*)args;
+    if (cb_info->return_value != RT_NULL)
+    {
+        js_emit_event(cb_info->this_value, cb_info->event_name, cb_info->return_value, cb_info->return_count);
+    }
+    else
+    {
+        js_emit_event(cb_info->this_value, cb_info->event_name, RT_NULL, 0);
+    }
+    
+    if (cb_info->return_value != RT_NULL)
+    {
+        for(int i = 0 ; i < cb_info->return_count ; i++)
+        {
+            jerry_release_value(cb_info->return_value[i]);
+        }
+        free(cb_info->return_value);
+    }
+    free(cb_info->event_name);
+    free(cb_info);
+}
+
+void mqtt_free_callback(const void *args, uint32_t size)
+{
+    
+}
+void mqtt_func_callback(const void *args, uint32_t size)
+{
+    mqtt_cbinfo_t *cb_info = (mqtt_cbinfo_t *)args;
+    jerry_value_t ret = jerry_call_function(cb_info->js_func, cb_info->this_value, RT_NULL, 0);
+    jerry_release_value(ret);
+    free(cb_info);
+}
+
+void mqtt_sub_callback(MQTTClient *c, MessageData *msg_data)
+{
+    mqtt_info_t* mqtt_info = (mqtt_info_t *)(c->user_data);
+    struct js_callback* event_callback = mqtt_info->event_callback;
+    
+    char* topicName = (char*)malloc((msg_data->topicName->lenstring.len+1)*sizeof(char));
+    memset(topicName, 0, msg_data->topicName->lenstring.len+1);
+    memcpy(topicName,msg_data->topicName->lenstring.data,msg_data->topicName->lenstring.len);
+    
+    js_buffer_t *js_buffer;
+    jerry_value_t js_payload = jerry_buffer_create(msg_data->message->payloadlen, &js_buffer);
+    if (js_buffer)
+    {
+        js_set_property(js_payload, "length", jerry_create_number(js_buffer->bufsize));
+        rt_memcpy(js_buffer->buffer, msg_data->message->payload, msg_data->message->payloadlen);
+    }
+    
+    /*emit message event*/
+    mqtt_cbinfo_t* cb_info = (mqtt_cbinfo_t*)malloc(sizeof(mqtt_cbinfo_t));
+    memset(cb_info, 0, sizeof(mqtt_cbinfo_t));
+
+    cb_info->this_value  = mqtt_info->this_value;
+    cb_info->return_value = (jerry_value_t *)malloc(sizeof(jerry_value_t)*2);
+    cb_info->return_value[0] = jerry_create_string((const jerry_char_t*)(topicName));
+    cb_info->return_value[1] = js_payload;
+    cb_info->return_count = 2;
+    cb_info->js_func = RT_NULL;
+    cb_info->event_name = rt_strdup("message");
+
+    js_send_callback(event_callback,cb_info,sizeof(mqtt_cbinfo_t));
+    free(cb_info);
+
+    /*emit topic's publish callback*/
+    for(int i =0 ; i < MAX_MESSAGE_HANDLERS ; i++)
+    {
+        if(strcmp(mqtt_info->callbackHandler[i].topic,topicName) == 0)
+        {
+            mqtt_cbinfo_t* cb_info = (mqtt_cbinfo_t*)malloc(sizeof(mqtt_cbinfo_t));
+            memset(cb_info, 0, sizeof(mqtt_cbinfo_t));
+
+            cb_info->this_value  = mqtt_info->this_value;
+            cb_info->return_value = RT_NULL;
+            cb_info->return_count = 0;
+            cb_info->js_func = mqtt_info->callbackHandler[i].js_func;
+
+            js_send_callback(mqtt_info->fun_callback, cb_info, sizeof(mqtt_cbinfo_t));
+            free(cb_info);
+            break;
+        }
+    }
+    free(topicName);
+
+    return;
+}
+
+void mqtt_connect_callback(MQTTClient *c)
+{
+    LOG_D("inter mqtt_connect_callback!");
+    //to do
+}
+
+void mqtt_online_callback(MQTTClient *c)
+{
+    LOG_D("inter mqtt_online_callback!");
+
+    mqtt_info_t* mqtt_info = (mqtt_info_t *)(c->user_data);
+    struct js_callback* event_callback = mqtt_info->event_callback;
+    
+    mqtt_cbinfo_t* cb_info = (mqtt_cbinfo_t*)malloc(sizeof(mqtt_cbinfo_t));
+    memset(cb_info, 0, sizeof(mqtt_cbinfo_t));
+    cb_info->this_value  = mqtt_info->this_value;
+    cb_info->return_value = RT_NULL;
+    cb_info->js_func = RT_NULL;
+    cb_info->event_name = rt_strdup("connect");
+
+    js_send_callback(event_callback,cb_info,sizeof(mqtt_cbinfo_t));
+    free(cb_info);
+}
+
+void mqtt_offline_callback(MQTTClient *c)
+{
+    LOG_D("inter mqtt_offline_callback!");
+    
+    mqtt_info_t* mqtt_info = (mqtt_info_t *)(c->user_data);
+    struct js_callback* event_callback = mqtt_info->event_callback;
+    
+    mqtt_cbinfo_t* cb_info = (mqtt_cbinfo_t*)malloc(sizeof(mqtt_cbinfo_t));
+    memset(cb_info, 0, sizeof(mqtt_cbinfo_t));
+    cb_info->this_value  = mqtt_info->this_value;
+    cb_info->return_value = RT_NULL;
+    cb_info->event_name = rt_strdup("offline");
+
+    js_send_callback(event_callback, cb_info, sizeof(mqtt_cbinfo_t));
+    free(cb_info);
+}
+
+void mqtt_client_free_callback(void *native_p)
+{
+    rt_kprintf("=============free call back============\n");
+    mqtt_info_t* mqtt_info =  (mqtt_info_t*)native_p;
+
+    if(!mqtt_info)
+    {
+        rt_kprintf("close >> null\n");
+    }
+    
+    if(mqtt_info->client->isconnected == 1)
+    {
+        MQTT_CMD(mqtt_info->client,"DISCONNECT");
+    }
+
+    rt_kprintf("1\n");
+    if(mqtt_info->sem)
+    {
+        rt_sem_delete(mqtt_info->sem);
+        mqtt_info->sem = RT_NULL;
+    }
+    js_destroy_emitter(mqtt_info->this_value);
+
+    rt_kprintf("2\n");
+    if(mqtt_info->close_callback)
+    {
+        js_remove_callback(mqtt_info->close_callback);
+    }
+    
+    if(mqtt_info->event_callback)
+    {
+        js_remove_callback(mqtt_info->event_callback);
+    }
+
+    if(mqtt_info->fun_callback)
+    {
+        js_remove_callback(mqtt_info->fun_callback);
+    }
+
+    rt_kprintf("3\n");
+    if(mqtt_info->client)
+    {
+        rt_kprintf("3-1\n");
+        if(mqtt_info->client->uri)
+        {
+            free((void*)mqtt_info->client->uri);
+        }
+        rt_kprintf("3-2\n");
+        if(mqtt_info->client->buf)
+        {
+            free(mqtt_info->client->buf);
+        }
+        rt_kprintf("3-3\n");
+        if(mqtt_info->client->readbuf)
+        {
+            free(mqtt_info->client->readbuf);
+        }
+        rt_kprintf("3-4\n");
+        for(int i =0 ; i < MAX_MESSAGE_HANDLERS ; i++)
+        {
+            if(mqtt_info->client->messageHandlers[i].topicFilter)
+            {
+                rt_kprintf("free topic : %s\n",mqtt_info->client->messageHandlers[i].topicFilter);
+                free(mqtt_info->client->messageHandlers[i].topicFilter);
+            }
+        }
+        free(mqtt_info->client);
+    }
+
+    rt_kprintf("4\n");
+    for(int i =0 ; i < MAX_MESSAGE_HANDLERS ; i++)
+    {
+        if(mqtt_info->callbackHandler[i].topic)
+        {
+            free(mqtt_info->callbackHandler[i].topic);
+            mqtt_info->callbackHandler[i].topic = RT_NULL;
+            mqtt_info->callbackHandler[i].js_func = RT_NULL;
+        }
+    }
+    rt_kprintf("5\n");
+    free(mqtt_info);
+    
+    hasClient = false;
+    rt_kprintf("end\n");
+}
+
+const static jerry_object_native_info_t mqtt_client_info =
+{
+    mqtt_client_free_callback
+};
+
+void get_mqtt_info(void **info, jerry_value_t js_target)
+{
+    jerry_value_t js_info = js_get_property(js_target, "info");
+    jerry_get_object_native_pointer(js_info, info, NULL);
+    jerry_release_value(js_info);
+}
+
+DECLARE_HANDLER(connect)
+{
+    mqtt_info_t *mqtt_info = RT_NULL;
+    get_mqtt_info((void **)&mqtt_info, this_value);
+    
+    paho_mqtt_start(mqtt_info->client);
+    
+    return jerry_create_undefined();
+}
+DECLARE_HANDLER(publish)
+{
+    mqtt_info_t *mqtt_info = RT_NULL;
+    get_mqtt_info((void **)&mqtt_info, this_value);
+    
+    char *topic;
+    unsigned char* send_str;
+    int length = 0;
+    int qos = 1;
+    bool dup = false;
+    bool retain = false;
+    jerry_value_t js_pub_callback = RT_NULL;
+
+    switch(args_cnt)
+    {
+        case 4:
+            if(jerry_value_is_function(args[3]))
+            {
+                js_pub_callback = args[3];
+            }
+            else
+            {
+                LOG_E("the 4rd parameter is not function");
+                goto _exit;
+            }
+        case 3:
+            if(jerry_value_is_function(args[2]))
+            {
+                js_pub_callback = args[2];
+            }
+            else if(jerry_value_is_object(args[2]))
+            {
+                if(jerry_value_is_object(js_get_property(args[2],"qos")))
+                {
+                    qos = jerry_get_number_value(js_get_property(args[2],"qos"));
+                    
+                    if(qos < 0)
+                    {
+                        qos = 0;
+                    }
+                    else if(qos > 2)
+                    {
+                        qos = 2;
+                    }
+                }
+                
+                if(jerry_value_is_boolean(js_get_property(args[2],"dup")))
+                {
+                    dup = jerry_value_to_boolean(js_get_property(args[2],"dup"));
+                }
+                
+                if(jerry_value_is_boolean(js_get_property(args[2],"retain")))
+                {
+                    retain = jerry_value_to_boolean(js_get_property(args[2],"retain"));
+                }
+            }
+            else
+            {
+                LOG_E("the 3nd parameter is not object or func");
+                goto _exit;
+            }
+        case 2:
+            if(jerry_value_is_string(args[1]))
+            {
+                send_str =  (unsigned char *)js_value_to_string(args[1]);
+                length = strlen((const char *)send_str);
+            }
+            else if(jerry_value_is_object(args[1]))
+            {
+                js_buffer_t *js_buffer = jerry_buffer_find(args[1]);
+                if(js_buffer)
+                {
+                    send_str = js_buffer->buffer;
+                    length = js_buffer->bufsize;
+                }
+            }
+            else
+            {
+                LOG_E("the 1st parameter is not string or buffer");
+                goto _exit;
+            }
+        case 1 : 
+            if(jerry_value_is_string(args[0]))
+            {
+                topic = js_value_to_string(args[0]);
+            }
+            else
+            {
+                LOG_E("the 1st parameter is not string");
+                goto _exit;
+            }
+            break;
+        default:
+            LOG_E("the count of parameters is wrong");
+            goto _exit;
+            break;
+    }
+    rt_sem_take(mqtt_info->sem,RT_WAITING_FOREVER);
+    MQTTMessage message;
+    
+    message.qos = qos;
+    message.retained = retain;
+    message.payload = (void *)send_str;
+    message.payloadlen = length;
+
+    MQTTPublish(mqtt_info->client, topic, &message);
+    
+    if(js_pub_callback != RT_NULL)
+    {
+        for(int i =0 ; i < MAX_MESSAGE_HANDLERS ; i++)
+        {
+            if(mqtt_info->callbackHandler[i].topic == RT_NULL)
+            {
+                mqtt_info->callbackHandler[i].topic = topic;
+                mqtt_info->callbackHandler[i].js_func = js_pub_callback;
+                break;
+            }
+        }
+    }
+    rt_sem_release(mqtt_info->sem);
+    free(send_str);
+    free(topic);
+    _exit:
+    return jerry_create_undefined();
+}
+DECLARE_HANDLER(subscribe)
+{
+    mqtt_info_t *mqtt_info = RT_NULL;
+    get_mqtt_info((void **)&mqtt_info, this_value);
+    
+    if(mqtt_info->subCount == MAX_MESSAGE_HANDLERS)
+    {
+        LOG_E("the count of topics is max");
+        goto _exit;
+    }
+    
+    jerry_value_t js_callback;
+    int qos = 0;
+    char* topic = RT_NULL;
+    jerry_value_t js_sub_callback;
+    switch(args_cnt)
+    {
+        case 3:
+            if(jerry_value_is_function(args[2]))
+            {
+                js_sub_callback = args[2];
+            }
+            else
+            {
+                LOG_E("the 3rd parameter is not function");
+                goto _exit;
+            }
+        case 2:
+            if(jerry_value_is_object(args[1]) && jerry_value_is_number(js_get_property(args[1],"qos")))
+            {
+                qos = jerry_get_number_value(js_get_property(args[1],"qos"));
+                
+                if(qos < 0)
+                {
+                    qos = 0;
+                }
+                else if(qos > 2)
+                {
+                    qos = 2;
+                }
+            }
+            else if(jerry_value_is_function(args[1]))
+            {
+                js_sub_callback = args[1];
+            }
+            else
+            {
+                LOG_E("the 2nd parameter is not number or func");
+                goto _exit;
+            }
+        case 1 : 
+            if(jerry_value_is_string(args[0]))
+            {
+                topic = js_value_to_string(args[0]);
+            }
+            else
+            {
+                LOG_E("the 1st parameter is not string");
+                goto _exit;
+            }
+            break;
+        default:
+            LOG_E("the count of parameters is wrong");
+            goto _exit;
+            break;
+    }
+    rt_sem_take(mqtt_info->sem, RT_WAITING_FOREVER);
+    for(int i = 0 ; i < MAX_MESSAGE_HANDLERS ; i++)
+    {
+        if(rt_strcmp(topic,mqtt_info->client->messageHandlers[i].topicFilter) == 0)
+        {
+            free(topic);
+            rt_sem_release(mqtt_info->sem);
+            goto _exit;
+            break;
+        }
+    }
+    
+    int index;
+    for(index = 0; index < MAX_MESSAGE_HANDLERS ; index++)
+    {
+        if(mqtt_info->client->messageHandlers[index].topicFilter == RT_NULL)
+        {
+            mqtt_info->client->messageHandlers[index].topicFilter =topic;
+            mqtt_info->client->messageHandlers[index].callback = mqtt_sub_callback;
+            mqtt_info->client->messageHandlers[index].qos = qos;
+            
+
+            mqtt_info->subCount++;
+            
+            if(mqtt_info->client->isconnected == 1)
+            {
+                MQTT_CMD(mqtt_info->client,"RECONNECT");
+            }
+            
+            /*emit the callback*/
+            if(js_sub_callback)
+            {
+                mqtt_cbinfo_t* cb_info = (mqtt_cbinfo_t*)malloc(sizeof(mqtt_cbinfo_t));
+                memset(cb_info, 0, sizeof(mqtt_cbinfo_t));
+                cb_info->this_value  = this_value;
+                cb_info->return_value = RT_NULL;
+                cb_info->js_func = js_sub_callback;
+                cb_info->event_name = RT_NULL;
+
+                js_send_callback(mqtt_info->fun_callback,cb_info,sizeof(mqtt_cbinfo_t));
+                free(cb_info);
+            }
+            break;
+        }
+    }
+    rt_sem_release(mqtt_info->sem);
+
+    
+    _exit:
+    return jerry_create_undefined();
+}
+
+DECLARE_HANDLER(unsubscribe)
+{
+    mqtt_info_t *mqtt_info = RT_NULL;
+    get_mqtt_info((void **)&mqtt_info, this_value);
+    
+    jerry_value_t js_unsub_callback = RT_NULL;
+    char* topic;
+    switch(args_cnt)
+    {
+        case 2:
+            if(jerry_value_is_function(args[1]))
+            {
+                js_unsub_callback = args[1];
+            }
+            else
+            {
+                goto _exit;
+            }
+        case 1 : 
+            if(jerry_value_is_string(args[0]))
+            {
+                topic = js_value_to_string(args[0]);
+            }
+            else
+            {
+                goto _exit;
+            }
+            break;
+        default:
+            goto _exit;
+            break;
+    }
+    rt_sem_take(mqtt_info->sem, RT_WAITING_FOREVER);
+    for(int i = 0 ; i < MAX_MESSAGE_HANDLERS ; i++)
+    {
+        if(strcmp(topic,mqtt_info->client->messageHandlers[i].topicFilter) == 0)
+        {
+            /*free data*/
+            free(mqtt_info->client->messageHandlers[i].topicFilter);
+            mqtt_info->client->messageHandlers[i].topicFilter = RT_NULL;
+            
+            /*restart mqtt*/
+            mqtt_info->subCount--;
+            if(mqtt_info->client->isconnected == 1)
+            {
+                MQTT_CMD(mqtt_info->client,"RECONNECT");
+            }
+            
+            /*emit the callback*/
+            if(js_unsub_callback)
+            {
+                mqtt_cbinfo_t* cb_info = (mqtt_cbinfo_t*)malloc(sizeof(mqtt_cbinfo_t));
+                memset(cb_info, 0, sizeof(mqtt_cbinfo_t));
+                cb_info->this_value  = this_value;
+                cb_info->return_value = RT_NULL;
+                cb_info->js_func = js_unsub_callback;
+                cb_info->event_name = RT_NULL;
+
+                js_send_callback(mqtt_info->fun_callback,cb_info,sizeof(mqtt_cbinfo_t));
+                free(cb_info);
+            }
+            
+            for(int i =0 ; i < MAX_MESSAGE_HANDLERS ; i++)
+            {
+                if(strcmp(mqtt_info->callbackHandler[i].topic,topic) == 0)
+                {
+                    free(mqtt_info->callbackHandler[i].topic);
+                    mqtt_info->callbackHandler[i].topic = RT_NULL;
+                    mqtt_info->callbackHandler[i].js_func = RT_NULL;
+                }
+            }
+            break;
+        }
+    }
+    free(topic);
+    rt_sem_release(mqtt_info->sem);
+    _exit:
+    return jerry_create_undefined();
+}
+DECLARE_HANDLER(end)
+{
+    mqtt_info_t *mqtt_info = RT_NULL;
+    get_mqtt_info((void **)&mqtt_info, this_value);
+    
+    jerry_value_t js_end_callback = RT_NULL;
+    bool force;
+    switch(args_cnt)
+    {
+        case 2:
+            if(jerry_value_is_function(args[1]))
+            {
+                js_end_callback = args[1];
+            }
+            else
+            {
+                goto _exit;
+            }
+        case 1 : 
+            if(jerry_value_is_boolean(args[0]))
+            {
+                force = jerry_value_to_boolean(args[0]);
+            } 
+            else if(jerry_value_is_function(args[0]))
+            {
+                js_end_callback = args[0];
+            }
+            else
+            {
+                goto _exit;
+            }
+            break;
+        default:
+            goto _exit;
+            break;
+    }
+    
+    if(mqtt_info->client->isconnected == 1)
+    {
+        MQTT_CMD(mqtt_info->client,"DISCONNECT");
+        
+        /*emit the callback*/
+        if(js_end_callback)
+        {
+            mqtt_cbinfo_t* cb_info = (mqtt_cbinfo_t*)malloc(sizeof(mqtt_cbinfo_t));
+            memset(cb_info, 0, sizeof(mqtt_cbinfo_t));
+            cb_info->this_value  = this_value;
+            cb_info->return_value = RT_NULL;
+            cb_info->js_func = js_end_callback;
+            cb_info->event_name = RT_NULL;
+
+            js_send_callback(mqtt_info->fun_callback,cb_info,sizeof(mqtt_cbinfo_t));
+            free(cb_info);
+        }
+    }
+_exit:
+    return jerry_create_undefined();
+}
+DECLARE_HANDLER(reconnect)
+{
+    mqtt_info_t *mqtt_info = RT_NULL;
+    get_mqtt_info((void **)&mqtt_info, this_value);
+    
+    if(mqtt_info->client->isconnected == 1)
+    {
+        MQTT_CMD(mqtt_info->client,"RECONNECT");
+    }
+    else
+    {
+        paho_mqtt_start(mqtt_info->client);
+    }
+    
+    return jerry_create_undefined();
+}
+
+
+static jerry_value_t mqtt_create_client(int arg_cnt,const jerry_value_t* args)
+{
+    jerry_value_t js_client = jerry_create_object();
+    mqtt_info_t* client_info = RT_NULL;
+
+    rt_kprintf("hasClient  : %d \n",hasClient);
+    if(hasClient == true)
+    {
+        goto _exit;
+    }
+
+    client_info = (mqtt_info_t*)malloc(sizeof(mqtt_info_t));
+    memset(client_info, 0, sizeof(mqtt_info_t));
+
+    if(!client_info)
+    {
+        goto _exit;
+    }
+    
+    client_info->client = (MQTTClient*)malloc(sizeof(MQTTClient));
+    if(!client_info->client)
+    {
+        goto _exit;
+    }
+
+    /*initialize MQTTClient* client */
+    client_info->client->isconnected = 0;
+    client_info->client->uri = js_value_to_string(args[0]);
+    client_info->client->toClose = 0;
+    client_info->client->user_data = (void*)client_info;
+    MQTTPacket_connectData condata = MQTTPacket_connectData_initializer;
+    memcpy(&(client_info->client->condata), &condata, sizeof(condata));
+
+    static char cid[20] = { 0 };
+    rt_snprintf(cid, sizeof(cid), "rtthread%d", rt_tick_get());
+    client_info->client->condata.clientID.cstring = cid;
+    client_info->client->condata.keepAliveInterval = 60;
+    client_info->client->condata.cleansession = 1;
+    client_info->client->reconnectPeriod = 1000; //1s
+    client_info->client->connectTimeout = 30*1000;   //30s
+    client_info->client->condata.username.cstring = RT_NULL;
+    client_info->client->condata.password.cstring = RT_NULL;
+
+    for(int i = 0 ; i < MAX_MESSAGE_HANDLERS ; i++)
+    {
+        client_info->client->messageHandlers[i].callback = RT_NULL;
+        client_info->client->messageHandlers[i].qos = QOS0;
+        client_info->client->messageHandlers[i].topicFilter = RT_NULL;
+    }
+    /* config MQTT will param. */
+    client_info->client->condata.willFlag = 0;
+
+    /*set the options of client*/
+    if(arg_cnt == 2)
+    {
+        jerry_value_t js_keepalive = js_get_property(args[1],"keepalive");
+        if(jerry_value_is_number(js_keepalive))
+        {
+            client_info->client->condata.keepAliveInterval = jerry_get_number_value(js_keepalive);
+        }
+        jerry_release_value(js_keepalive);
+        
+        jerry_value_t js_clientId = js_get_property(args[1], "clientId");
+        if(jerry_value_is_string(js_clientId))
+        {
+            char* cid = js_value_to_string(js_clientId);
+            client_info->client->condata.clientID.cstring = cid;
+            free(cid);
+        }
+        jerry_release_value(js_clientId);
+        
+        jerry_value_t js_clean = js_get_property(args[1],"clean");
+        if(jerry_value_is_boolean(js_clean))
+        {
+            client_info->client->condata.cleansession = jerry_value_to_boolean(js_clean);
+        }
+        jerry_release_value(js_clean);
+        
+        jerry_value_t js_reconnectPeriod = js_get_property(args[1],"reconnectPeriod");
+        if(jerry_value_is_number(js_reconnectPeriod))
+        {
+            client_info->client->reconnectPeriod = jerry_get_number_value(js_reconnectPeriod);
+        }
+        jerry_release_value(js_reconnectPeriod);
+        
+        jerry_value_t js_connectTimeout = js_get_property(args[1],"connectTimeout");
+        if(jerry_value_is_number(js_connectTimeout))
+        {
+            client_info->client->connectTimeout = jerry_get_number_value(js_connectTimeout);
+        }
+        jerry_release_value(js_connectTimeout);
+        
+        jerry_value_t js_username = js_get_property(args[1], "username");
+        if(jerry_value_is_string(js_username))
+        {
+            char* username = js_value_to_string(js_username);
+            client_info->client->condata.username.cstring = username;
+            free(username);
+        }
+        jerry_release_value(js_username);
+        
+        jerry_value_t js_password = js_get_property(args[1], "password");
+        if(jerry_value_is_string(js_password))
+        {
+            char* password = js_value_to_string(js_password);
+            client_info->client->condata.password.cstring = password;
+            free(password);
+        }
+        jerry_release_value(js_password);
+        
+        jerry_value_t js_will =  js_get_property(args[1],"will");
+        if(jerry_value_is_object(js_will))
+        {
+            client_info->client->condata.willFlag = 1;
+            client_info->client->condata.will.qos = 0;
+            client_info->client->condata.will.retained = 0;
+            
+            jerry_value_t js_will_topic = js_get_property(js_will,"topic");
+            if(jerry_value_is_string(js_will_topic))
+            {
+                char* will_topic = js_value_to_string(js_will_topic);
+                client_info->client->condata.will.topicName.cstring = will_topic;
+                free(will_topic);
+                jerry_release_value(js_will_topic);
+            }
+            else
+            {
+                jerry_release_value(js_will_topic);
+                goto _exit;
+            }
+            
+            jerry_value_t js_will_message = js_get_property(js_will,"payload");
+            if(jerry_value_is_string(js_will_message))
+            {
+                char* will_message = js_value_to_string(js_will_message);
+                client_info->client->condata.will.topicName.cstring = will_message;
+                free(will_message);
+                jerry_release_value(js_will_topic);
+            }
+            else
+            {
+                jerry_release_value(js_will_topic);
+                goto _exit;
+            }
+
+            jerry_value_t js_will_qos = js_get_property(js_will,"qos");
+            if(jerry_value_is_number(js_will_message))
+            {
+                int qos = jerry_get_number_value(js_will_qos);
+                if(qos < 0)
+                {
+                    qos =0;
+                }
+                else if(qos > 2)
+                {
+                    qos = 2;
+                }
+                client_info->client->condata.will.qos = qos;
+            }
+            jerry_release_value(js_will_qos);
+            
+            jerry_value_t js_will_retain = js_get_property(js_will,"retain");
+            if(jerry_value_is_number(js_will_retain))
+            {
+                client_info->client->condata.will.retained = jerry_value_to_boolean(js_will_retain);
+            }
+            jerry_release_value(js_will_retain);
+        }
+    }
+    
+    /* malloc buffer. */
+    client_info->client->buf_size = client_info->client->readbuf_size = 1024;
+    client_info->client->buf = malloc(client_info->client->buf_size);
+    client_info->client->readbuf = malloc(client_info->client->readbuf_size);
+    if (!(client_info->client->buf && client_info->client->readbuf))
+    {
+        goto _exit;
+    }
+    
+    /*create sem*/
+    client_info->sem = rt_sem_create("mqtt_msghandler_semt", 1, RT_IPC_FLAG_FIFO);
+
+    js_make_emitter(js_client, jerry_create_undefined());
+    
+    /*add js event callback*/
+    client_info->fun_callback = js_add_callback(mqtt_func_callback);
+    client_info->event_callback = js_add_callback(mqtt_event_callback);
+    client_info->close_callback = js_add_callback(mqtt_free_callback);
+    
+    /* set client's event callback function */
+    client_info->client->connect_callback = mqtt_connect_callback;
+    client_info->client->online_callback = mqtt_online_callback;
+    client_info->client->offline_callback = mqtt_offline_callback;
+
+    /*create js object*/
+    jerry_value_t js_info = jerry_create_object();
+    client_info->this_value = js_client;
+    js_set_property(js_client, "info", js_info);
+    jerry_set_object_native_pointer(js_info, client_info, &mqtt_client_info);  // set native_pointer
+    jerry_release_value(js_info);
+    /*set method*/
+    REGISTER_METHOD_NAME(js_client, "connect", connect);
+    REGISTER_METHOD_NAME(js_client, "publish", publish);
+    REGISTER_METHOD_NAME(js_client, "subscribe", subscribe);
+    REGISTER_METHOD_NAME(js_client, "unsubscribe", unsubscribe);
+    REGISTER_METHOD_NAME(js_client, "end", end);
+    REGISTER_METHOD_NAME(js_client, "reconnect", reconnect);
+
+    hasClient = true;
+
+    return (js_client);
+    _exit:
+    jerry_release_value(js_client);
+    if(client_info)
+    {
+        if(client_info->client)
+        {
+            free(client_info->client);
+        }
+        
+        free(client_info);
+    }
+    return jerry_create_undefined();
+}
+
+DECLARE_HANDLER(Client)
+{
+    if(args_cnt >2 ||args_cnt ==0)
+    {
+        return jerry_create_undefined();
+    }
+
+    switch(args_cnt)
+    {
+        case 2:
+            if(!jerry_value_is_object(args[1]))
+            {
+                return jerry_create_undefined();
+            }
+        case 1:
+            if(!jerry_value_is_string(args[0]))
+            {
+                return jerry_create_undefined();
+            }
+        default:
+            break;
+    }
+    
+    jerry_value_t js_client = mqtt_create_client(args_cnt,args);
+    return js_client;
+}
+
+DECLARE_HANDLER(client_connect)
+{
+    if(args_cnt >2 ||args_cnt ==0)
+    {
+        return jerry_create_undefined();
+    }
+
+    switch(args_cnt)
+    {
+        case 2:
+            if(!jerry_value_is_object(args[1]))
+            {
+                return jerry_create_undefined();
+            }
+        case 1:
+            if(!jerry_value_is_string(args[0]))
+            {
+                return jerry_create_undefined();
+            }
+        default:
+            break;
+    }
+    
+    jerry_value_t js_client =  mqtt_create_client(args_cnt,args);
+    
+    mqtt_info_t *mqtt_info = RT_NULL;
+    get_mqtt_info((void **)&mqtt_info, this_value);
+    
+    paho_mqtt_start(mqtt_info->client);
+
+    return js_client;
+}
+
+static jerry_value_t jerry_mqtt_init()
+{
+    jerry_value_t js_mqtt = jerry_create_object();
+
+    REGISTER_METHOD_NAME(js_mqtt, "Client", Client);
+    REGISTER_METHOD_NAME(js_mqtt, "connect", client_connect);
+
+    return js_mqtt;
+}
+
+JS_MODULE(mqtt, jerry_mqtt_init)

+ 47 - 0
rtthread-port/jerry_mqtt.h

@@ -0,0 +1,47 @@
+#ifndef JERRY_MQTT_H__
+#define JERRY_MQTT_H__
+
+#include <rtthread.h>
+
+#ifdef PKG_USING_PAHOMQTT
+
+#include <jerry_util.h>
+#include <jerry_event.h>
+#include <jerry_callbacks.h>
+#include <jerry_buffer.h>
+#include "paho_mqtt.h"
+
+#define MQTT_BUFFER_SIZE 1024
+
+struct mqtt_callback_info
+{
+    jerry_value_t this_value;
+    jerry_value_t js_func;
+    int return_count;
+    jerry_value_t* return_value;
+    char* event_name;
+}typedef mqtt_cbinfo_t;
+    
+struct mqtt_client_info
+{
+    jerry_value_t this_value;
+    int subCount; //the count of topics subscribed
+    MQTTClient* client;
+    
+    struct js_callback* event_callback;
+    struct js_callback* fun_callback;
+    struct js_callback* close_callback;
+
+    struct topic_callback_list
+    {
+        char* topic;
+        jerry_value_t js_func;
+    }callbackHandler[MAX_MESSAGE_HANDLERS];
+    
+    rt_sem_t sem;
+}typedef mqtt_info_t;
+
+
+#endif
+
+#endif

+ 1448 - 0
rtthread-port/jerry_net.c

@@ -0,0 +1,1448 @@
+#include "jerry_net.h"
+/* manage the pipe of socket */
+static rt_int32_t pipe_init(struct socket_info *thiz)
+{
+    char dname[8];
+    char dev_name[32];
+    static int pipeno = 0;
+
+    if (thiz == RT_NULL)
+    {
+        return -1;
+    }
+
+    snprintf(dname, sizeof(dname), "Socket%d", pipeno++);
+
+    thiz->pipe = rt_pipe_create(dname, PIPE_BUFSZ);
+    if (thiz->pipe == RT_NULL)
+    {
+        return -1;
+    }
+
+    snprintf(dev_name, sizeof(dev_name), "/dev/%s", dname);
+    thiz->pipe_read_fd = open(dev_name, O_RDONLY, 0);
+    if (thiz->pipe_read_fd < 0)
+    {
+        rt_kprintf("pipe_read_fd open failed\n");
+        return -1;
+    }
+
+    thiz->pipe_write_fd = open(dev_name, O_WRONLY, 0);
+    if (thiz->pipe_write_fd < 0)
+    {
+        close(thiz->pipe_read_fd);
+        rt_kprintf("pipe_write_fd open failed\n");
+        return -1;
+    }
+    return 0;
+}
+
+static rt_int32_t pipe_deinit(struct socket_info *thiz)
+{
+    if (thiz == RT_NULL)
+    {
+        return -1;
+    }
+
+    close(thiz->pipe_read_fd);
+    close(thiz->pipe_write_fd);
+    rt_pipe_delete((const char *)thiz->pipe);
+    return 0;
+}
+
+/* manage the socket_list */
+int get_socket_list_count(socket_list_t **l)
+{
+    if (*l == RT_NULL)
+    {
+        return 0;
+    }
+
+    int count = 0;
+    socket_list_t *start = *l;
+    do
+    {
+        count++;
+        *l = (*l)->next;
+    }
+    while ((*l) != start);
+
+    return count;
+}
+
+void socket_list_init(socket_list_t **l, jerry_value_t socket)
+{
+    (*l)->next = (*l)->prev = (*l);
+    (*l)->js_socket = socket;
+}
+
+void socket_list_insert(socket_list_t **l, jerry_value_t socket)
+{
+    if (*l == RT_NULL)
+    {
+        *l = (socket_list_t *)malloc(sizeof(socket_list_t));
+        socket_list_init(l, socket);
+    }
+    else
+    {
+        socket_list_t *n = (socket_list_t *)malloc(sizeof(socket_list_t));
+        socket_list_init(&n, socket);
+
+        (*l)->next->prev = n;
+        n->next = (*l)->next;
+        (*l)->next = n;
+        n->prev = (*l);
+    }
+}
+
+void socket_list_remove(socket_list_t **n)
+{
+    if ((*n)->next == (*n))
+    {
+        free((*n));
+        (*n) = RT_NULL;
+    }
+    else
+    {
+        (*n)->next->prev = (*n)->prev;
+        (*n)->prev->next = (*n)->next;
+        (*n)->next = (*n)->prev = (*n);
+        free(*n);
+        (*n) = RT_NULL;
+    }
+}
+
+bool socket_list_remove_by_socket(socket_list_t **l, jerry_value_t socket)
+{
+    if ((*l) == RT_NULL || socket == RT_NULL)
+    {
+        return false;
+    }
+
+    socket_list_t *start = (*l);
+    do
+    {
+        if ((*l)->js_socket == socket)
+        {
+            socket_list_t *toRemove = *l;
+            (*l) = (*l)->next;
+            if ((*l) != toRemove)
+            {
+                socket_list_remove(&toRemove);
+            }
+            else
+            {
+                socket_list_remove(l);
+            }
+            return true;
+        }
+        (*l) = (*l)->next;
+    }
+    while ((*l) != start);
+
+    return false;
+}
+
+void socket_list_remove_all(socket_list_t **l)
+{
+    if ((*l) == RT_NULL)
+    {
+        return;
+    }
+
+    socket_list_t *start = (*l);
+    do
+    {
+        socket_list_t *toRemove = *l;
+        (*l) = (*l)->next;
+        if ((*l) != toRemove)
+        {
+            socket_list_remove(&toRemove);
+        }
+        else
+        {
+            socket_list_remove(l);
+        }
+
+        (*l) = (*l)->next;
+    }
+    while ((*l) != start);
+}
+
+/* the callbacks of Net Module */
+void get_net_info(void **info, jerry_value_t js_target)
+{
+    jerry_value_t js_info = js_get_property(js_target, "info");
+    jerry_get_object_native_pointer(js_info, info, NULL);
+    jerry_release_value(js_info);
+}
+
+void net_event_callback_func(const void *args, uint32_t size)
+{
+    net_event_info *cb_info = (net_event_info *)args;
+
+    if (cb_info->js_return != RT_NULL)
+    {
+        js_emit_event(cb_info->js_target, cb_info->event_name, &cb_info->js_return, 1);
+    }
+    else
+    {
+        js_emit_event(cb_info->js_target, cb_info->event_name, NULL, 0);
+    }
+
+    if (cb_info->js_return != RT_NULL && cb_info->js_return != cb_info->js_target)//&& strcmp(cb_info->event_name, "connection") != 0 )
+    {
+        jerry_release_value(cb_info->js_return);;
+    }
+
+    free(cb_info->event_name);
+    free(cb_info);
+}
+
+void net_socket_callback_func(const void *args, uint32_t size)
+{
+    net_funcInfo_t *cb_info = (net_funcInfo_t *)args;
+
+    jerry_value_t ret = jerry_call_function(cb_info->js_run, cb_info->js_this, (jerry_value_t *)cb_info->args, cb_info->args_cnt);
+
+    jerry_release_value(ret);
+    free(cb_info);
+}
+
+void net_server_close(jerry_value_t js_server)
+{
+    net_serverInfo_t *js_server_info = RT_NULL;
+    get_net_info((void **)&js_server_info, js_server);
+    /*emit 'close' event*/
+    net_event_info *event_info = (net_event_info *)malloc(sizeof(net_event_info));
+    memset(event_info, 0, sizeof(net_event_info));
+
+    event_info->event_name = strdup("close");
+    event_info->js_target = js_server;
+    event_info->js_return = RT_NULL;
+
+    js_send_callback(js_server_info->event_callback, event_info, sizeof(net_event_info));
+    free(event_info);
+
+    /*do close callback of server*/
+    net_closeInfo_t *close_info  = (net_closeInfo_t *)malloc(sizeof(net_closeInfo_t));
+    memset(close_info, 0, sizeof(net_closeInfo_t));
+
+    close_info->js_server = js_server;
+    close_info->js_socket = RT_NULL;
+
+    js_send_callback(js_server_info->close_callback, close_info, sizeof(net_closeInfo_t));
+    free(close_info);
+}
+
+void net_socket_callback_free(const void *args, uint32_t size)
+{
+    net_closeInfo_t *close_info = (net_closeInfo_t *)args;
+
+    struct socket_info *js_socket_info = RT_NULL;
+    get_net_info((void **)&js_socket_info, close_info->js_socket);
+    jerry_value_t js_server = js_socket_info->js_server;
+
+    if (js_socket_info->readData_thread != RT_NULL)
+    {
+        rt_thread_delete(js_socket_info->readData_thread);
+        js_socket_info->readData_thread = RT_NULL;
+    }
+    closesocket(js_socket_info->socket_id);
+    js_socket_info->socket_id = -1;
+
+    js_remove_callback(js_socket_info->event_callback);
+    js_remove_callback(js_socket_info->fun_callback);
+    js_remove_callback(js_socket_info->close_callback);
+
+    pipe_deinit(js_socket_info);
+
+    rt_sem_delete(js_socket_info->socket_sem);
+    js_socket_info->socket_sem = RT_NULL;
+    js_destroy_emitter(close_info->js_socket);
+
+    if (close_info->js_server != RT_NULL)
+    {
+        /*get server info*/
+        net_serverInfo_t *js_server_info = RT_NULL;
+        get_net_info((void **)&js_server_info, js_server);
+
+        rt_sem_take(js_server_info->server_sem, RT_WAITING_FOREVER);
+        socket_list_remove_by_socket(&(js_server_info->socket_list), close_info->js_socket);
+        rt_sem_release(js_server_info->server_sem);
+
+        if (js_server_info->server_id == -1 && get_socket_list_count(&(js_server_info->socket_list)) == 0)
+        {
+            net_server_close(js_server);
+        }
+    }
+    free(close_info);
+}
+
+void net_socket_free_callback(void *native_p)
+{
+    struct socket_info *js_socket_info = (struct socket_info *)native_p;
+
+    if (!js_socket_info)
+    {
+        return;
+    }
+
+    closesocket(js_socket_info->socket_id);
+    js_socket_info->socket_id = -1;
+    js_remove_callback(js_socket_info->event_callback);
+    js_remove_callback(js_socket_info->fun_callback);
+    js_remove_callback(js_socket_info->close_callback);
+    pipe_deinit(js_socket_info);
+
+    if (js_socket_info->socket_sem)
+    {
+        rt_sem_delete(js_socket_info->socket_sem);
+        js_destroy_emitter(js_socket_info->this_value);
+        if (js_socket_info->js_server != RT_NULL)
+        {
+            /*get server info*/
+            net_serverInfo_t *js_server_info = RT_NULL;
+            get_net_info((void **)&js_server_info, js_socket_info->js_server);
+
+            rt_sem_take(js_server_info->server_sem, RT_WAITING_FOREVER);
+            socket_list_remove_by_socket(&(js_server_info->socket_list), js_socket_info->this_value);
+            rt_sem_release(js_server_info->server_sem);
+
+            if (js_server_info->server_id == -1 && get_socket_list_count(&(js_server_info->socket_list)) == 0)
+            {
+                net_server_close(js_socket_info->js_server);
+            }
+        }
+    }
+
+    free(js_socket_info);
+}
+
+void net_server_callback_free(const void *args, uint32_t size)
+{
+    rt_kprintf(">> net_server_callback_free \n");
+    net_closeInfo_t *close_info = (net_closeInfo_t *)args;
+
+    net_serverInfo_t *js_server_info = RT_NULL;
+    get_net_info((void **)&js_server_info, close_info->js_server);
+
+    if (js_server_info->listen_thread != RT_NULL)
+    {
+        rt_thread_delete(js_server_info->listen_thread);
+        js_server_info->listen_thread = RT_NULL;
+    }
+
+    if (js_server_info->server_id != -1)
+    {
+        closesocket(js_server_info->server_id);
+        js_server_info->server_id = -1;
+    }
+
+    js_remove_callback(js_server_info->event_callback);
+    js_remove_callback(js_server_info->close_callback);
+
+    rt_sem_delete(js_server_info->server_sem);
+    js_server_info->server_sem = RT_NULL;
+    js_destroy_emitter(close_info->js_server);
+
+    free(close_info);
+}
+
+void net_server_free_callback(void *native_p)
+{
+    net_serverInfo_t *js_server_info = (net_serverInfo_t *)native_p;
+
+    if (!js_server_info)
+    {
+        return;
+    }
+
+    if (js_server_info->listen_thread != RT_NULL)
+    {
+        rt_thread_delete(js_server_info->listen_thread);
+    }
+
+    if (js_server_info->server_id != -1)
+    {
+        closesocket(js_server_info->server_id);
+    }
+
+    js_remove_callback(js_server_info->event_callback);
+    js_remove_callback(js_server_info->close_callback);
+
+    if (js_server_info->server_sem != RT_NULL)
+    {
+        rt_sem_delete(js_server_info->server_sem);
+        js_server_info->server_sem = RT_NULL;
+        js_destroy_emitter(js_server_info->this_value);
+    }
+    free(js_server_info);
+}
+
+const static jerry_object_native_info_t net_server_info =
+{
+    net_server_free_callback
+};
+
+const static jerry_object_native_info_t net_socket_info =
+{
+    net_socket_free_callback
+};
+
+/*  the method of socket  */
+void net_socket_readData(jerry_value_t js_socket)
+{
+    unsigned char buffer[BUFFER_SIZE];
+    memset(&buffer, 0, BUFFER_SIZE);
+
+    struct socket_info *js_socket_info = RT_NULL;
+    get_net_info((void **)&js_socket_info, js_socket);
+    int bytesRead = recv(js_socket_info->socket_id, buffer, BUFFER_SIZE + 1, 0);
+
+    /*set property: data*/
+    js_buffer_t *js_buffer;
+    jerry_value_t data_value = jerry_buffer_create(bytesRead, &js_buffer);
+    if (js_buffer)
+    {
+        js_set_property(data_value, "length", jerry_create_number(js_buffer->bufsize));
+        rt_memcpy(js_buffer->buffer, buffer, bytesRead);
+    }
+
+    /*emit 'data' event*/
+    net_event_info *event_info = (net_event_info *)malloc(sizeof(net_event_info));
+    memset(event_info, 0, sizeof(net_event_info));
+
+    event_info->event_name = strdup("data");
+    event_info->js_target = js_socket;
+    event_info->js_return = data_value;
+
+    js_send_callback(js_socket_info->event_callback, event_info, sizeof(net_event_info));
+    free(event_info);
+}
+
+void net_socket_sendData(net_writeInfo_t *write_info, jerry_value_t js_socket)
+{
+    unsigned char buffer[BUFFER_SIZE];
+    memset(&buffer, 0, BUFFER_SIZE);
+    /*send the data*/
+    int hasSent = 0;
+
+    struct socket_info *js_socket_info = RT_NULL;
+    get_net_info((void **)&js_socket_info, js_socket);
+
+    js_buffer_t *js_buffer = jerry_buffer_find(write_info->js_data);
+
+    if (js_buffer)
+    {
+        for (int i = 0, bytes = js_buffer->bufsize; bytes > 0; i++, bytes -= BUFFER_SIZE)
+        {
+            memset(&buffer, 0, BUFFER_SIZE);
+
+            if (bytes > BUFFER_SIZE)
+            {
+                memcpy(buffer, js_buffer->buffer + i * BUFFER_SIZE, BUFFER_SIZE);
+                hasSent += send(js_socket_info->socket_id, buffer, BUFFER_SIZE, 0);
+            }
+            else
+            {
+                memcpy(buffer, js_buffer->buffer + i * BUFFER_SIZE, bytes);
+                hasSent += send(js_socket_info->socket_id, buffer, bytes, 0);
+            }
+        }
+    }
+    else if (jerry_value_is_string(write_info->js_data))
+    {
+        char *js_str = js_value_to_string(write_info->js_data);
+        for (int i = 0, bytes = strlen(js_str); bytes > 0; i++, bytes -= BUFFER_SIZE)
+        {
+            memset(&buffer, 0, BUFFER_SIZE);
+
+            if (bytes > BUFFER_SIZE)
+            {
+                memcpy(buffer, js_str + i * BUFFER_SIZE, BUFFER_SIZE);
+                hasSent += send(js_socket_info->socket_id, buffer, BUFFER_SIZE, 0);
+            }
+            else
+            {
+                memcpy(buffer, js_str + i * BUFFER_SIZE, bytes);
+                hasSent += send(js_socket_info->socket_id, buffer, bytes, 0);
+            }
+        }
+        free(js_str);
+    }
+
+    /*do callback*/
+    if (hasSent && write_info->js_callback != RT_NULL)
+    {
+        net_funcInfo_t *func_info = (net_funcInfo_t *)malloc(sizeof(net_funcInfo_t));
+        memset(func_info, 0, sizeof(net_funcInfo_t));
+
+        func_info->js_run = write_info->js_callback;
+        func_info->js_this = js_socket;
+        func_info->args = RT_NULL;
+        func_info->args_cnt = 0;
+
+        js_send_callback(js_socket_info->fun_callback, func_info, sizeof(net_funcInfo_t));
+        free(func_info);
+    }
+}
+
+static void net_socket_readData_entry(void *p)
+{
+    jerry_value_t js_socket = ((net_readInfo_t *)p)->js_socket;
+    free(p);
+
+    struct socket_info *js_socket_info = RT_NULL;
+    get_net_info((void **)&js_socket_info, js_socket);
+    int socket = js_socket_info->socket_id;
+    int pipe_read_fd = js_socket_info->pipe_read_fd;
+
+    int max_fd = 0;
+    if (socket > pipe_read_fd)
+    {
+        max_fd = socket + 1;
+    }
+    else
+    {
+        max_fd = pipe_read_fd + 1;
+    }
+
+    fd_set readfds;
+
+    while (1)
+    {
+        FD_ZERO(&readfds);
+        FD_SET(socket, &readfds);
+        FD_SET(pipe_read_fd, &readfds);
+
+        if (js_socket_info->timeout.tv_sec == 0 && js_socket_info->timeout.tv_usec == 0)
+        {
+            select(max_fd, &readfds, 0, 0, 0);
+        }
+        else
+        {
+            if (select(max_fd, &readfds, 0, 0, &js_socket_info->timeout) == 0)
+            {
+                /*emit 'timeout' event*/
+                net_event_info *event_info = (net_event_info *)malloc(sizeof(net_event_info));
+                memset(event_info, 0, sizeof(net_event_info));
+
+                event_info->event_name = strdup("timeout");
+                event_info->js_target = js_socket;
+                event_info->js_return = RT_NULL;
+
+                js_send_callback(js_socket_info->event_callback, event_info, sizeof(net_event_info));
+                free(event_info);
+            }
+        }
+        if (FD_ISSET(socket, &readfds) && js_socket_info->readable == true)
+        {
+            net_socket_readData(js_socket);
+        }
+
+        if (FD_ISSET(pipe_read_fd, &readfds))
+        {
+            rt_sem_take(js_socket_info->socket_sem, RT_WAITING_FOREVER);
+            //read from pipe
+            static net_writeInfo_t write_info;
+            memset(&write_info, 0, sizeof(net_writeInfo_t));
+            int bytesRead = read(js_socket_info->pipe_read_fd, &write_info, sizeof(net_writeInfo_t));
+            net_socket_sendData(&write_info, js_socket);
+            rt_sem_release(js_socket_info->socket_sem);
+        }
+    }
+}
+
+/*start the read_thread of socket */
+void net_socket_startRead(jerry_value_t js_socket)
+{
+    /*get socket_info*/
+    struct socket_info *js_socket_info = RT_NULL;
+    get_net_info((void **)&js_socket_info, js_socket);
+
+    /*create a thread to read data from server*/
+    if (js_socket_info->allowHalfOpen == false)
+    {
+        net_readInfo_t *read_info = (net_readInfo_t *)malloc(sizeof(net_readInfo_t));
+        memset(read_info, 0, sizeof(net_readInfo_t));
+        read_info->js_socket = js_socket;
+        js_socket_info->readData_thread = rt_thread_create("socket_Read", net_socket_readData_entry, read_info, 2048, 20, 5);
+        rt_thread_startup(js_socket_info->readData_thread);
+    }
+    /*emit 'connect' event*/
+    net_event_info *event_info = (net_event_info *)malloc(sizeof(net_event_info));
+    memset(event_info, 0, sizeof(net_event_info));
+
+    event_info->event_name = strdup("connect");
+    event_info->js_target = js_socket;
+    event_info->js_return = RT_NULL;
+    js_send_callback(js_socket_info->event_callback, event_info, sizeof(net_event_info));
+    free(event_info);
+
+    if (js_socket_info->socket_id < 0)
+    {
+        return;
+    }
+}
+
+/*update property : remoteAddress , remoteFamily, remotePort, localAddress and localPort*/
+int net_socket_updateProperty(jerry_value_t js_socket)
+{
+    /*get socket_info*/
+    struct socket_info *js_socket_info = RT_NULL;
+    get_net_info((void **)&js_socket_info, js_socket);
+
+    if (js_socket_info->socket_id < 0)
+    {
+        return 0;
+    }
+    struct sockaddr_in remote_name; //get the infomation of remote address
+    socklen_t sin_size = sizeof(struct sockaddr_in);
+    getpeername(js_socket_info->socket_id, (struct sockaddr *)&remote_name, &sin_size);
+
+    jerry_value_t js_remoteFamily;
+    if (remote_name.sin_family == AF_INET)
+    {
+        js_remoteFamily = jerry_create_string((const jerry_char_t *)"IPv4");
+    }
+    else
+    {
+        js_remoteFamily = jerry_create_string((const jerry_char_t *)"IPv6");
+    }
+    js_set_property(js_socket, "remoteFamily", js_remoteFamily);
+    jerry_release_value(js_remoteFamily);
+
+    jerry_value_t js_remotePort = jerry_create_number(ntohs(remote_name.sin_port));
+    js_set_property(js_socket, "remotePort", js_remotePort);
+    jerry_release_value(js_remotePort);
+
+    jerry_value_t js_remoteAddress = jerry_create_string((jerry_char_t *)inet_ntoa(remote_name.sin_addr));
+    js_set_property(js_socket, "remoteAddress", js_remoteAddress);
+    jerry_release_value(js_remoteAddress);
+    /*update property : localAddress and localPort*/
+
+    struct sockaddr_in local_name; //get the infomation of local address
+    getsockname(js_socket_info->socket_id, (struct sockaddr *)&local_name, &sin_size);
+
+    jerry_value_t js_localAddress = jerry_create_string((jerry_char_t *)inet_ntoa(local_name.sin_addr));
+    js_set_property(js_socket, "localAddress", js_localAddress);
+    jerry_release_value(js_localAddress);
+
+    jerry_value_t js_localPort = jerry_create_number(ntohs(local_name.sin_port));
+    js_set_property(js_socket, "localPort", js_localPort);
+    jerry_release_value(js_localPort);
+
+    return 1;
+}
+
+DECLARE_HANDLER(socket_connect)
+{
+    if (args_cnt == 0 || args_cnt > 3)
+    {
+        return jerry_create_undefined();
+    }
+
+    /*relative informations*/
+    int port = -1;
+    char *host = RT_NULL;
+    int family = 4;
+
+    jerry_value_t js_connect_cb = RT_NULL;
+    /*get socket_info*/
+    struct socket_info *js_socket_info = RT_NULL;
+    get_net_info((void **)&js_socket_info, this_value);
+
+    if (jerry_value_is_object(args[0]))
+    {
+        jerry_value_t js_port = js_get_property(args[0], "port");
+        if (jerry_value_is_number(js_port))
+        {
+            port = jerry_get_number_value(js_port);
+        }
+        jerry_release_value(js_port);
+
+        jerry_value_t js_host = js_get_property(args[0], "host");
+        if (jerry_value_is_string(js_host))
+        {
+            host = js_value_to_string(js_host);
+        }
+        jerry_release_value(js_host);
+
+        jerry_value_t js_family = js_get_property(args[0], "family");
+        if (jerry_value_is_number(js_family))
+        {
+            family = jerry_get_number_value(js_family);
+        }
+        jerry_release_value(js_family);
+    }
+
+    if (jerry_value_is_number(args[0]))
+    {
+        port = jerry_get_number_value(args[0]);
+    }
+
+    if (args_cnt > 1 && jerry_value_is_string(args[1]))
+    {
+        host = js_value_to_string(args[1]);
+    }
+
+    if (args_cnt > 1 && jerry_value_is_function(args[1]))
+    {
+        js_connect_cb = args[1];
+    }
+    else if (args_cnt > 2 && jerry_value_is_function(args[2]))
+    {
+        js_connect_cb = args[2];
+    }
+
+    /*add connect event listener*/
+    if (js_connect_cb != RT_NULL)
+    {
+        js_add_event_listener(this_value, "connect", js_connect_cb);
+    }
+
+    /*create socket*/
+    if (js_socket_info->socket_id == -1)
+    {
+        if (family == 4)
+        {
+            js_socket_info->socket_id = socket(PF_INET, SOCK_STREAM, 0);
+        }
+#if LWIP_IPV6
+        else if (family == 6)
+        {
+            js_socket_info->server_socket = socket(PF_INET6, SOCK_STREAM, 0);
+        }
+#endif
+        else
+        {
+            rt_kprintf("the paramater named 'family' is wrong\n");
+            return jerry_create_undefined();
+        }
+    }
+    else
+    {
+        goto __isConnected;
+    }
+
+    /*read to connect*/
+    if (port > 0)
+    {
+        struct sockaddr_in socket_fd;
+
+        socket_fd.sin_family = AF_INET;
+
+#if LWIP_IPV6
+        if (family == 6)
+            socket_fd.sin_family = AF_INET6;
+#endif
+
+        struct hostent *socket_host;
+        socket_host = gethostbyname(host);
+        socket_fd.sin_addr = *((struct in_addr *)socket_host->h_addr);
+        socket_fd.sin_port = htons(port);
+        rt_memset(&(socket_fd.sin_zero), 0, sizeof(socket_fd.sin_zero));
+
+        int ret = connect(js_socket_info->socket_id, (struct sockaddr *)&socket_fd, sizeof(struct sockaddr));
+        if (ret >= 0)
+        {
+__isConnected:
+            if(net_socket_updateProperty(this_value))
+            {
+                net_socket_startRead(this_value);
+            }
+        }
+    }
+    else
+    {
+        rt_kprintf("the paramater named 'port' is wrong\n");
+        return jerry_create_undefined();
+    }
+
+    free(host);
+    return jerry_acquire_value(this_value);
+}
+
+DECLARE_HANDLER(socket_destory)
+{
+    /*get socket_info*/
+    struct socket_info *js_socket_info = RT_NULL;
+    get_net_info((void **)&js_socket_info, this_value);
+
+    if (js_socket_info->socket_id == -1)
+    {
+        return jerry_create_undefined();
+    }
+
+    net_closeInfo_t *close_info  = (net_closeInfo_t *)malloc(sizeof(net_closeInfo_t));
+    memset(close_info, 0, sizeof(net_closeInfo_t));
+
+    close_info->js_server = js_socket_info->js_server;
+    close_info->js_socket = this_value;
+
+    js_send_callback(js_socket_info->close_callback, close_info, sizeof(net_closeInfo_t));
+    free(close_info);
+    return jerry_create_undefined();
+}
+
+DECLARE_HANDLER(socket_end)
+{
+    if (args_cnt == 0 || args_cnt > 2)
+    {
+        return jerry_create_undefined();
+    }
+    /*get socket_info*/
+    struct socket_info *js_socket_info = RT_NULL;
+    get_net_info((void **)&js_socket_info, this_value);
+
+    if (js_socket_info->socket_id == -1)
+    {
+        return jerry_create_undefined();
+    }
+
+    /*get wirte andy destory function*/
+    jerry_value_t js_socket_write = js_get_property(this_value, "write");
+    jerry_value_t js_socket_destory = js_get_property(this_value, "destory");
+
+    if (jerry_value_is_function(js_socket_write) && jerry_value_is_function(js_socket_destory))
+    {
+        jerry_call_function(js_socket_write, this_value, args, args_cnt);
+        jerry_call_function(js_socket_destory, this_value, NULL, 0);
+    }
+
+    jerry_release_value(js_socket_write);
+    jerry_release_value(js_socket_destory);
+    return this_value;
+}
+
+DECLARE_HANDLER(socket_pause)
+{
+    /*get socket_info*/
+    struct socket_info *js_socket_info = RT_NULL;
+    get_net_info((void **)&js_socket_info, this_value);
+
+    if (js_socket_info->socket_id == -1)
+    {
+        return jerry_create_undefined();
+    }
+
+    if (js_socket_info->readData_thread != 0)
+    {
+        rt_thread_suspend(js_socket_info->readData_thread);
+    }
+
+    return jerry_create_undefined();
+}
+
+DECLARE_HANDLER(socket_resume)
+{
+    /*get socket_info*/
+    struct socket_info *js_socket_info = RT_NULL;
+    get_net_info((void **)&js_socket_info, this_value);
+
+    if (js_socket_info->socket_id == -1)
+    {
+        return jerry_create_undefined();
+    }
+
+    if (js_socket_info->readData_thread != 0)
+    {
+        rt_thread_resume(js_socket_info->readData_thread);
+    }
+
+    return jerry_create_undefined();
+}
+
+DECLARE_HANDLER(socket_setTimeout)
+{
+    if (args_cnt == 0 || args_cnt > 2)
+    {
+        return jerry_create_undefined();
+    }
+
+    /*get socket_info*/
+    struct socket_info *js_socket_info = RT_NULL;
+    get_net_info((void **)&js_socket_info, this_value);
+
+    if (js_socket_info->socket_id == -1)
+    {
+        return jerry_create_undefined();
+    }
+
+    int utime = 0 ;
+    if (jerry_value_is_number(args[0]))
+    {
+        utime = jerry_get_number_value(args[0]);
+    }
+
+    if (utime < 0)
+    {
+        return jerry_create_undefined();
+    }
+
+    js_socket_info->timeout.tv_usec = utime * 1000;
+
+    if (args_cnt == 2 && jerry_value_is_function(args[1]))
+    {
+        js_add_event_listener(this_value, "timeout", args[1]);
+    }
+
+    return jerry_create_undefined();
+}
+
+DECLARE_HANDLER(socket_write)
+{
+    if (args_cnt == 0 || args_cnt > 2)
+    {
+        return jerry_create_undefined();
+    }
+
+    /*get socket_info*/
+    struct socket_info *js_socket_info = RT_NULL;
+    get_net_info((void **)&js_socket_info, this_value);
+
+    if (js_socket_info->socket_id == -1)
+    {
+        return jerry_create_undefined();
+    }
+
+    if (js_socket_info->writable == true)
+    {
+        net_writeInfo_t write_info;
+        memset(&write_info, 0, sizeof(net_writeInfo_t));
+        write_info.js_data = args[0];
+        if (args_cnt == 2 && jerry_value_is_function(args[1]))
+        {
+            write_info.js_callback = args[1];
+        }
+        else
+        {
+            write_info.js_callback = RT_NULL;
+        }
+        write(js_socket_info->pipe_write_fd, &write_info, sizeof(net_writeInfo_t));
+    }
+    return jerry_create_undefined();
+}
+
+jerry_value_t create_js_socket()
+{
+    jerry_value_t js_socket = jerry_create_object();
+
+    struct socket_info *js_socket_info = (struct socket_info *)malloc(sizeof(struct socket_info));
+    memset(js_socket_info, 0, sizeof(struct socket_info));
+    int ret = pipe_init(js_socket_info);
+    if (ret == -1)
+    {
+        rt_kprintf("net module create pipe failed\n");
+        free(js_socket_info);
+        jerry_release_value(js_socket);
+        return jerry_create_undefined();
+    }
+    js_socket_info->js_server = RT_NULL;
+    js_socket_info->this_value = js_socket;
+    /*set method*/
+    REGISTER_METHOD_NAME(js_socket, "connect", socket_connect);
+    REGISTER_METHOD_NAME(js_socket, "destory", socket_destory);
+    REGISTER_METHOD_NAME(js_socket, "end", socket_end);
+    REGISTER_METHOD_NAME(js_socket, "pause", socket_pause);
+    REGISTER_METHOD_NAME(js_socket, "resume", socket_resume);
+    REGISTER_METHOD_NAME(js_socket, "setTimeout", socket_setTimeout);
+    REGISTER_METHOD_NAME(js_socket, "write", socket_write);
+
+    /* set property*/
+    if (js_socket_info)
+    {
+        jerry_value_t js_info = jerry_create_object();
+        js_set_property(js_socket, "info", js_info);
+        jerry_set_object_native_pointer(js_info, js_socket_info, &net_socket_info);  // set native_pointer
+        jerry_release_value(js_info);
+
+        // initialize the socket_info
+        js_socket_info->socket_id = -1;
+        js_socket_info->allowHalfOpen = false;
+        js_socket_info->writable = true;
+        js_socket_info->readable = true;
+        js_socket_info->event_callback = js_add_callback(net_event_callback_func);
+        js_socket_info->fun_callback = js_add_callback(net_socket_callback_func);
+        js_socket_info->close_callback = js_add_callback(net_socket_callback_free);
+        js_socket_info->socket_sem = rt_sem_create("socket_sem", 1, RT_IPC_FLAG_FIFO);
+        js_socket_info->timeout.tv_sec = 0;
+        js_socket_info->timeout.tv_usec = 0;
+
+        jerry_value_t js_localAddress = jerry_create_undefined();
+        js_set_property(js_socket, "localAddress", js_localAddress);
+        jerry_release_value(js_localAddress);
+
+        jerry_value_t js_localPort = jerry_create_undefined();
+        js_set_property(js_socket, "localPort", js_localPort);
+        jerry_release_value(js_localPort);
+
+        jerry_value_t js_remoteAddress = jerry_create_undefined();
+        js_set_property(js_socket, "remoteAddress", js_remoteAddress);
+        jerry_release_value(js_remoteAddress);
+
+        jerry_value_t js_remoteFamily = jerry_create_undefined();
+        js_set_property(js_socket, "remoteFamily", js_remoteFamily);
+        jerry_release_value(js_remoteFamily);
+
+        jerry_value_t js_remotePort = jerry_create_undefined();
+        js_set_property(js_socket, "remotePort", js_remotePort);
+        jerry_release_value(js_remotePort);
+    }
+    return js_socket;
+}
+
+DECLARE_HANDLER(net_Socket)
+{
+    if (args_cnt > 1)
+        return jerry_create_undefined();
+
+    jerry_value_t js_socket = create_js_socket();
+    if (jerry_value_is_undefined(js_socket))
+        return jerry_create_undefined();
+
+    /*get socket_info*/
+    js_make_emitter(js_socket, jerry_create_undefined());
+
+    struct socket_info *js_socket_info = RT_NULL;
+    get_net_info((void **)&js_socket_info, js_socket);
+
+    //get options value and set the paramaters
+    if (args_cnt == 1 && jerry_value_is_object(args[0]))
+    {
+        jerry_value_t js_fd = js_get_property(args[0], "fd");
+        if (jerry_value_is_number(js_fd))
+        {
+            js_socket_info->socket_id = jerry_get_number_value(js_fd);
+        }
+        jerry_release_value(js_fd);
+
+        jerry_value_t js_allowHalfOpen  = js_get_property(args[0], "allowHalfOpen");
+        if (jerry_value_is_boolean(js_allowHalfOpen))
+        {
+            js_socket_info->allowHalfOpen = jerry_get_boolean_value(js_allowHalfOpen);
+        }
+        jerry_release_value(js_allowHalfOpen);
+
+        jerry_value_t js_writable  = js_get_property(args[0], "writable");
+        if (jerry_value_is_boolean(js_writable))
+        {
+            js_socket_info->writable = jerry_get_boolean_value(js_writable);
+        }
+        jerry_release_value(js_writable);
+
+        jerry_value_t js_readable  = js_get_property(args[0], "readable");
+        if (jerry_value_is_boolean(js_readable))
+        {
+            js_socket_info->writable = jerry_get_boolean_value(js_readable);
+        }
+        jerry_release_value(js_readable);
+    }
+    return (js_socket);
+}
+
+/*  the method of server  */
+static void net_server_listen_entry(void *listen_info)
+{
+    jerry_value_t js_server = ((net_listenInfo_t *)listen_info)->js_server;
+    int backlog = ((net_listenInfo_t *)listen_info)->backlog;
+
+    free(listen_info);
+
+    /*get socket_info*/
+    net_serverInfo_t *js_server_info = RT_NULL;
+    get_net_info((void **)&js_server_info, js_server);
+    int socket_id = js_server_info->server_id;
+    rt_sem_t server_sem = js_server_info->server_sem;
+
+    /*start listening and accepting*/
+    if (socket > 0)
+    {
+        int ret = listen(socket_id, backlog); // start listen
+        struct sockaddr_in client_addr;
+        socklen_t addrlen = 1;
+
+        rt_kprintf("SERVER_MAX_CONNECTIONS : %d \n", backlog);
+        while (1)
+        {
+            memset(&client_addr, 0, sizeof(struct sockaddr_in));
+            int client_fd = accept(socket_id, (struct sockaddr *)&client_addr, &addrlen); //accept ths client socket
+            /*judge whether the new client are allow to connect*/
+            rt_sem_take(server_sem, RT_WAITING_FOREVER);
+
+            int client_count = get_socket_list_count(&js_server_info->socket_list);
+            rt_sem_release(server_sem);
+            if (client_fd && client_count < backlog)
+            {
+                /*set the option of new_socket func*/
+                jerry_value_t js_new_socket_option = jerry_create_object();
+
+                jerry_value_t js_socket_allowHalfOpen = jerry_create_boolean(js_server_info->allowHalfOpen);
+                js_set_property(js_new_socket_option, "allowHalfOpen", js_socket_allowHalfOpen);
+                jerry_release_value(js_socket_allowHalfOpen);
+
+                jerry_value_t js_socket_fd = jerry_create_number(client_fd);
+                js_set_property(js_new_socket_option, "fd", js_socket_fd);
+                jerry_release_value(js_socket_fd);
+
+                /*do new_socket func*/
+                jerry_value_t js_new_socket = jerry_create_external_function(net_Socket_handler);
+                jerry_value_t js_socket = jerry_call_function(js_new_socket, jerry_create_undefined(), &js_new_socket_option, 1);
+                jerry_release_value(js_new_socket_option);
+                jerry_release_value(js_new_socket);
+
+                if (jerry_value_is_undefined(js_socket))
+                {
+                    jerry_release_value(js_socket);
+                    closesocket(client_fd);
+                }
+                else
+                {
+                    /*set the socket's server*/
+                    struct socket_info *js_socket_info = RT_NULL;
+                    get_net_info((void **)&js_socket_info, js_socket);
+                    js_socket_info->js_server = js_server;
+
+                    /*add js_socket to socket_list*/
+                    rt_sem_take(server_sem, RT_WAITING_FOREVER);
+
+                    socket_list_insert(&js_server_info->socket_list, js_socket);
+                    client_count = get_socket_list_count(&js_server_info->socket_list);
+                    net_socket_updateProperty(js_socket);
+
+                    rt_sem_release(server_sem);
+                    /*emit 'connention' event*/
+                    /*send the new socket to connection listener of js_server*/
+                    net_event_info *event_info = (net_event_info *)malloc(sizeof(net_event_info));
+                    memset(event_info, 0, sizeof(net_event_info));
+
+                    event_info->event_name = strdup("connection");
+                    event_info->js_target = js_server;
+                    event_info->js_return = js_socket;
+                    js_send_callback(js_server_info->event_callback, event_info, sizeof(net_event_info));
+                    free(event_info);
+                }
+            }
+            else
+            {
+                closesocket(client_fd);
+            }
+
+        }
+    }
+}
+DECLARE_HANDLER(server_close)
+{
+    /*get server info*/
+    net_serverInfo_t *js_server_info = RT_NULL;
+    get_net_info((void **)&js_server_info, this_value);
+
+    if (!js_server_info)
+    {
+        js_destroy_emitter(this_value);
+        return jerry_create_undefined();
+    }
+    if (args_cnt > 1)
+    {
+        return jerry_create_undefined();
+    }
+
+    if (args_cnt > 0 && jerry_value_is_function(args[0]))
+    {
+        js_add_event_listener(this_value, "close", args[0]);
+    }
+
+    /*stop listening*/
+    if (js_server_info->listen_thread != RT_NULL)
+    {
+        rt_thread_delete(js_server_info->listen_thread);
+        js_server_info->listen_thread = RT_NULL;
+    }
+
+    if (js_server_info->server_id != -1)
+    {
+        closesocket(js_server_info->server_id);
+        js_server_info->server_id = -1;
+    }
+
+    if (get_socket_list_count(&(js_server_info->socket_list)) == 0)
+    {
+        net_server_close(this_value);
+    }
+
+    return jerry_create_undefined();
+}
+
+DECLARE_HANDLER(server_listen)
+{
+    if (args_cnt == 0 || args_cnt > 4)
+        return jerry_create_undefined();
+
+    /*get server info*/
+    net_serverInfo_t *js_server_info = RT_NULL;
+    get_net_info((void **)&js_server_info, this_value);
+    /*end listen_thread*/
+    //rt_thread_delete(js_server_info->listen_thread);
+    //js_server_info->listen_thread = RT_NULL;
+    /*the value of option*/
+    int port = -1;
+    char *host = RT_NULL;
+    int backlog = SERVER_MAX_CONNECTIONS;
+    int family = 4;
+
+    jerry_value_t js_listen_cb = RT_NULL;
+#if LWIP_IPV6
+    family = 6;
+#endif
+
+    if (jerry_value_is_object(args[0]))
+    {
+        jerry_value_t js_port = js_get_property(args[0], "port");
+        if (jerry_value_is_number(js_port))
+        {
+            port = jerry_get_number_value(js_port);
+        }
+        jerry_release_value(js_port);
+
+        jerry_value_t js_host = js_get_property(args[0], "host");
+        if (jerry_value_is_string(js_host))
+        {
+            host = js_value_to_string(js_host);
+        }
+        jerry_release_value(js_host);
+
+        jerry_value_t js_backlog = js_get_property(args[0], "backlog");
+        if (jerry_value_is_number(js_backlog))
+        {
+            int count = jerry_get_number_value(js_backlog);
+            if (count < backlog)
+            {
+                backlog = count;
+            }
+        }
+        jerry_release_value(js_backlog);
+
+        if (args_cnt == 2 && jerry_value_is_function(args[1]))
+        {
+            js_listen_cb = args[1];
+        }
+    }
+    else if (jerry_value_is_number(args[0]))
+    {
+        switch (args_cnt)
+        {
+        case 4 :
+            if (jerry_value_is_string(args[3]))
+            {
+                host = js_value_to_string(args[3]);
+            }
+            else if (jerry_value_is_number(args[3]))
+            {
+                backlog = jerry_get_number_value(args[3]);
+            }
+            else if (jerry_value_is_function(args[3]))
+            {
+                js_listen_cb = args[3];
+            }
+        case 3 :
+            if (jerry_value_is_string(args[2]))
+            {
+                host = js_value_to_string(args[2]);
+            }
+            else if (jerry_value_is_number(args[2]))
+            {
+                backlog = jerry_get_number_value(args[2]);
+            }
+            else if (jerry_value_is_function(args[2]))
+            {
+                js_listen_cb = args[2];
+            }
+        case 2 :
+            if (jerry_value_is_string(args[1]))
+            {
+                host = js_value_to_string(args[1]);
+            }
+            else if (jerry_value_is_number(args[1]))
+            {
+                backlog = jerry_get_number_value(args[1]);
+            }
+            else if (jerry_value_is_function(args[1]))
+            {
+                js_listen_cb = args[1];
+            }
+        case 1 :
+            port = jerry_get_number_value(args[0]);
+        default:
+            break;
+        }
+    }
+
+    if (port < 0)
+    {
+        goto __exit;
+    }
+
+    /*create socket and bind*/
+    if (family == 4)
+    {
+        js_server_info->server_id = socket(AF_INET, SOCK_STREAM, 0);
+    }
+    else if (family == 6)
+    {
+        js_server_info->server_id = socket(AF_INET6, SOCK_STREAM, 0);
+    }
+
+    if (js_server_info->server_id > 0)
+    {
+        struct sockaddr_in server_addr;
+        if (family == 4)
+        {
+            server_addr.sin_family = AF_INET;
+        }
+        else if (family == 6)
+        {
+            server_addr.sin_family = AF_INET6;
+        }
+        if (host)
+        {
+            server_addr.sin_addr.s_addr = inet_addr(host);
+        }
+        else
+        {
+            server_addr.sin_addr.s_addr = INADDR_ANY;
+        }
+        server_addr.sin_port = htons(port);
+
+        const int on = 1;
+        setsockopt(js_server_info->server_id, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+        int ret = bind(js_server_info->server_id, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));;
+        if (ret == 0)
+        {
+            net_listenInfo_t *listen_info = (net_listenInfo_t *)malloc(sizeof(net_listenInfo_t));
+            memset(listen_info, 0, sizeof(net_listenInfo_t));
+            listen_info->js_server = this_value;
+            listen_info->backlog = backlog;
+
+            struct socket_info *js_socket_info = RT_NULL;
+            get_net_info((void **)&js_socket_info, this_value);
+
+            js_server_info->listen_thread = rt_thread_create("net_listen", net_server_listen_entry, listen_info, 1024, 20, 5);
+            rt_err_t ret = rt_thread_startup(js_server_info->listen_thread);
+
+            if (ret == RT_EOK)
+            {
+                /*emit 'listening' event*/
+                net_event_info *event_info = (net_event_info *)malloc(sizeof(net_event_info));
+                memset(event_info, 0, sizeof(net_event_info));
+
+                event_info->event_name = strdup("listening");
+                event_info->js_target = this_value;
+                event_info->js_return = RT_NULL;
+
+                js_send_callback(js_socket_info->event_callback, event_info, sizeof(net_event_info));
+                free(event_info);
+            }
+        }
+    }
+
+__exit:
+    jerry_release_value(js_listen_cb);
+    return jerry_create_undefined();
+}
+
+/* the method of net */
+DECLARE_HANDLER(net_connect)
+{
+    if (args_cnt == 0 || args_cnt > 3)
+    {
+        return jerry_create_undefined();
+    }
+
+    /* create socket */
+    jerry_value_t js_new_socket = js_get_property(this_value, "Socket");
+    jerry_value_t js_socket = jerry_call_function(js_new_socket, this_value, NULL, 0);
+    jerry_release_value(js_new_socket);
+
+    if (jerry_value_is_undefined(js_socket))
+    {
+        jerry_release_value(js_socket);
+        return jerry_create_undefined();
+    }
+    /* do socket.connect */
+    jerry_value_t js_socket_connect = js_get_property(js_socket, "connect");
+    jerry_value_t js_ret = jerry_call_function(js_socket_connect, js_socket, args, args_cnt);
+    jerry_release_value(js_socket_connect);
+
+    if (jerry_value_is_undefined(js_ret))
+    {
+        jerry_release_value(js_ret);
+        return jerry_create_undefined();
+    }
+
+    jerry_release_value(js_ret);
+    return js_socket;
+}
+
+DECLARE_HANDLER(net_createServer)
+{
+    jerry_value_t js_server = jerry_create_object();
+
+    /*add property of server*/
+    net_serverInfo_t *js_server_info = (net_serverInfo_t *)malloc(sizeof(net_serverInfo_t));
+    memset(js_server_info, 0, sizeof(net_serverInfo_t));
+
+    jerry_value_t js_info = jerry_create_object();
+    js_set_property(js_server, "info", js_info);
+    jerry_set_object_native_pointer(js_info, js_server_info, &net_server_info);  // set native_pointer
+    jerry_release_value(js_info);
+
+    js_make_emitter(js_server, jerry_create_undefined());
+
+    js_server_info->allowHalfOpen = false;
+    js_server_info->server_id = -1;
+    js_server_info->event_callback = js_add_callback(net_event_callback_func);
+    js_server_info->close_callback = js_add_callback(net_server_callback_free);
+    js_server_info->socket_list = RT_NULL;
+    js_server_info->server_sem = rt_sem_create("server_sem", 1, RT_IPC_FLAG_FIFO);
+    js_server_info->this_value = js_server;
+    if (args_cnt > 0 && jerry_value_is_object(args[0]))
+    {
+        jerry_value_t js_allowHalfOpen = js_get_property(args[0], "allowHalfOpen");
+
+        if (jerry_value_is_boolean(js_allowHalfOpen))
+        {
+            js_server_info->allowHalfOpen = jerry_value_to_boolean(js_allowHalfOpen);
+        }
+        jerry_release_value(js_allowHalfOpen);
+    }
+
+    if (args_cnt > 0 && jerry_value_is_function(args[0]))
+    {
+        js_add_event_listener(js_server, "connection", args[0]);
+    }
+    if (args_cnt > 1 && jerry_value_is_function(args[1]))
+    {
+        js_add_event_listener(js_server, "connection", args[1]);
+    }
+    /*register method to server*/
+    REGISTER_METHOD_NAME(js_server, "listen", server_listen);
+    REGISTER_METHOD_NAME(js_server, "close", server_close);
+
+    return (js_server);
+}
+
+jerry_value_t jerry_net_init()
+{
+
+    jerry_value_t js_net = jerry_create_object();
+
+    REGISTER_METHOD_NAME(js_net, "Socket", net_Socket);
+    REGISTER_METHOD_NAME(js_net, "connect", net_connect);
+    REGISTER_METHOD_NAME(js_net, "createConnection", net_connect);
+    REGISTER_METHOD_NAME(js_net, "createServer", net_createServer);
+
+    return (js_net);
+}
+
+JS_MODULE(net, jerry_net_init)

+ 110 - 0
rtthread-port/jerry_net.h

@@ -0,0 +1,110 @@
+#ifndef JERRY_NET_H__
+#define JERRY_NET_H__
+
+#include <rtthread.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <jerry_util.h>
+#include <jerry_event.h>
+#include <jerry_callbacks.h>
+#include <jerry_buffer.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/types.h>
+
+#define  BUFFER_SIZE 1024
+#define SERVER_MAX_CONNECTIONS (RT_LWIP_TCP_PCB_NUM - 3)
+
+struct socket_node
+{
+    struct socket_node *next;
+    struct socket_node *prev;
+    jerry_value_t js_socket;
+} typedef socket_list_t;
+
+struct socket_info
+{
+    int socket_id ;
+
+    int pipe_write_fd;
+    int pipe_read_fd;
+    struct rt_pipe_device *pipe;
+
+    bool allowHalfOpen ;
+    bool writable ;
+    bool readable ;
+
+    struct js_callback *event_callback;
+    struct js_callback *fun_callback;
+    struct js_callback *close_callback;
+
+    rt_thread_t readData_thread;
+
+    jerry_value_t js_server;
+    jerry_value_t this_value;
+    rt_sem_t socket_sem;
+    struct timeval timeout;
+} typedef net_socoketInfo_t;
+
+
+struct server_info
+{
+    int server_id;
+
+    bool allowHalfOpen;
+
+    struct js_callback *event_callback;
+    struct js_callback *close_callback;
+
+    rt_thread_t listen_thread;
+
+    socket_list_t *socket_list;
+    jerry_value_t this_value;
+
+    rt_sem_t server_sem;
+} typedef net_serverInfo_t;
+
+struct read_thread_info
+{
+    jerry_value_t js_socket;
+
+} typedef net_readInfo_t;
+
+struct listen_thread_info
+{
+    jerry_value_t js_server;
+    int backlog;
+} typedef net_listenInfo_t;
+
+struct write_data_info
+{
+    jerry_value_t js_data;
+    jerry_value_t js_callback;
+} typedef net_writeInfo_t;
+
+struct event_callback_info
+{
+    char *event_name;
+    jerry_value_t js_return;
+    jerry_value_t js_target;
+} typedef net_event_info;
+
+struct fun_callback_info
+{
+    void *args;
+    int args_cnt;
+    jerry_value_t js_run;
+    jerry_value_t js_this;
+} typedef net_funcInfo_t;
+
+struct close_callback_info
+{
+    jerry_value_t js_server;
+    jerry_value_t js_socket;
+} typedef net_closeInfo_t;
+
+#endif

+ 376 - 0
rtthread-port/jerry_request_init.c

@@ -0,0 +1,376 @@
+#include "jerry_request_init.h"
+
+#ifdef PKG_USING_WEBCLIENT
+void request_callback_func(const void *args, uint32_t size)
+{
+    request_cbinfo_t *cb_info = (request_cbinfo_t *)args;
+
+    if (cb_info->return_value != RT_NULL)
+    {
+        js_emit_event(cb_info->target_value, cb_info->callback_name, &cb_info->return_value, 1);
+    }
+    else
+    {
+        js_emit_event(cb_info->target_value, cb_info->callback_name, RT_NULL, 0);
+    }
+    if (cb_info->return_value != RT_NULL)
+    {
+        jerry_release_value(cb_info->return_value);
+    }
+    if (cb_info->data_value != RT_NULL)
+    {
+        jerry_release_value(cb_info->data_value);
+    }
+
+	free(cb_info->callback_name);
+    free(cb_info);
+}
+
+void request_callback_free(const void *args, uint32_t size)
+{
+    request_tdinfo_t *rp = (request_tdinfo_t *)args;
+    if (rp->session)
+    {
+        webclient_close(rp->session);
+    }
+    js_remove_callback(rp->request_callback);
+    js_remove_callback(rp->close_callback);
+    js_destroy_emitter(rp->target_value);
+    jerry_release_value(rp->target_value);
+    free(rp);
+}
+
+bool request_combine_header(struct webclient_session *session, char *host, char *user_agent, char *content_type)
+{
+    bool ret = false;
+    if (host != RT_NULL)
+    {
+        webclient_header_fields_add(session, "Host: %s\r\n", host);
+        free(host);
+        ret = true;
+    }
+    if (user_agent != RT_NULL)
+    {
+        webclient_header_fields_add(session, "User-Agent: %s\r\n", user_agent);
+        free(user_agent);
+        ret = true;
+    }
+    if (content_type != RT_NULL)
+    {
+        webclient_header_fields_add(session, "Content-Type: %s\r\n", content_type);
+        free(content_type);
+        ret = true;
+    }
+    return ret;
+}
+
+void request_create_header(struct webclient_session *session, jerry_value_t header_value)
+{
+    int enter_index = 0;
+    int colon_index = 0;
+    int per_enter_index = -1;
+    char header_type[64];
+    char header_info[128];
+    for (int i = 0 ; i < session->header->length ; i++)
+    {
+        if (session->header->buffer[i] == ':' && per_enter_index != enter_index)
+        {
+            colon_index = i;
+            per_enter_index = enter_index;
+            memset(header_type, 0, 64);
+            memset(header_info, 0, 128);
+            strncpy(header_type, session->header->buffer + enter_index + 1, colon_index - enter_index - 1);
+            strcpy(header_info, session->header->buffer + colon_index + 2);
+            jerry_value_t header_info_value = jerry_create_string((jerry_char_t *)header_info);
+            js_set_property(header_value, header_type, header_info_value);
+            jerry_release_value(header_info_value);
+        }
+        if (session->header->buffer[i] == '\0')
+            enter_index = i;
+    }
+}
+
+bool request_get_header(struct webclient_session *session, jerry_value_t header_value)
+{
+    if (jerry_value_is_object(header_value))
+    {
+        char *host = RT_NULL, *user_agent = RT_NULL, *content_type = RT_NULL;
+
+        jerry_value_t Host_value = js_get_property(header_value, "Host");
+        if (!jerry_value_is_undefined(Host_value))
+        {
+            host = js_value_to_string(Host_value);
+        }
+        jerry_release_value(Host_value);
+
+        jerry_value_t User_Agent_value = js_get_property(header_value, "User-Agent");
+        if (!jerry_value_is_undefined(User_Agent_value))
+        {
+            user_agent = js_value_to_string(User_Agent_value);
+        }
+        jerry_release_value(User_Agent_value);
+
+        jerry_value_t Content_Type_value = js_get_property(header_value, "Content-Type");
+        if (!jerry_value_is_undefined(Content_Type_value))
+        {
+            content_type = js_value_to_string(Content_Type_value);
+        }
+        jerry_release_value(Content_Type_value);
+
+        return request_combine_header(session, host, user_agent, content_type);
+    }
+    else
+    {
+        return false;
+    }
+}
+
+void request_read_entry(void *p)
+{
+    request_tdinfo_t *rp = (request_tdinfo_t *)p;
+
+    unsigned char *buffer = RT_NULL;
+    buffer = (unsigned char *)malloc(READ_MAX_SIZE + 1);
+    if (!buffer)
+    {
+        rt_kprintf("no more memory to create read buffer\n");
+        return;
+    }
+    memset(buffer, 0, READ_MAX_SIZE + 1);
+
+    //create a callback function to free manager and close webClient session
+    int ret_read = 0;
+    ret_read = webclient_read(rp->session, buffer, READ_MAX_SIZE + 1);
+    //If file's size is bigger than buffer's,
+    //give up reading and send a fail callback
+    if (ret_read > READ_MAX_SIZE)
+    {
+        rt_kprintf("the received message's size is bigger than buffer's\n");
+
+        request_cbinfo_t *fail_info = (request_cbinfo_t *)malloc(sizeof(request_cbinfo_t));
+        fail_info->target_value = rp->target_value;
+        fail_info->callback_name = rt_strdup("fail");
+        fail_info->return_value = RT_NULL;
+        fail_info->data_value = RT_NULL;
+        js_send_callback(rp->request_callback, fail_info, sizeof(request_cbinfo_t));
+        free(fail_info);
+    }
+    else
+    {
+        jerry_value_t return_value = jerry_create_object();
+
+        /*  create the jerry_value_t of res  */
+        js_buffer_t *js_buffer;
+        jerry_value_t data_value = jerry_buffer_create(ret_read, &js_buffer);
+        if (js_buffer)
+        {
+            jerry_value_t length_value = jerry_create_number(js_buffer->bufsize);
+            js_set_property(data_value, "length", length_value);
+            jerry_release_value(length_value);
+            rt_memcpy(js_buffer->buffer, buffer, ret_read);
+        }
+        js_set_property(return_value, "data", data_value);
+
+        jerry_value_t statusCode_value = jerry_create_number(webclient_resp_status_get(rp->session));
+        js_set_property(return_value, "statusCode", statusCode_value);
+        jerry_release_value(statusCode_value);
+
+        /*** header's data saved as Object ***/
+        jerry_value_t header_value = jerry_create_object();
+        request_create_header(rp->session, header_value);
+        js_set_property(return_value, "header", header_value);
+        jerry_release_value(header_value);
+
+        //do success callback
+        request_cbinfo_t *success_info  = (request_cbinfo_t *)malloc(sizeof(request_cbinfo_t));
+        memset(success_info, 0, sizeof(request_cbinfo_t));
+        success_info->target_value = rp->target_value;
+        success_info->callback_name = rt_strdup("success");
+        success_info->return_value = return_value;
+        success_info->data_value = data_value;
+        js_send_callback(rp->request_callback, success_info, sizeof(request_cbinfo_t));
+        free(success_info);
+    }
+
+    //do complete callback
+    request_cbinfo_t *complete_info  = (request_cbinfo_t *)malloc(sizeof(request_cbinfo_t));;
+    complete_info->target_value = rp->target_value;
+    complete_info->callback_name = rt_strdup("complete");
+    complete_info->return_value = RT_NULL;
+    complete_info->data_value = RT_NULL;
+    js_send_callback(rp->request_callback, complete_info, sizeof(request_cbinfo_t));
+    free(complete_info);
+
+    free(buffer);
+    js_send_callback(rp->close_callback, rp, sizeof(request_cbinfo_t));
+    free(rp);
+}
+
+void requeset_add_event_listener(jerry_value_t js_target, jerry_value_t requestObj)
+{
+    jerry_value_t success_func = js_get_property(requestObj, "success");
+    if (jerry_value_is_function(success_func))
+    {
+        js_add_event_listener(js_target, "success", success_func);
+    }
+    jerry_release_value(success_func);
+
+    jerry_value_t fail_func = js_get_property(requestObj, "fail");
+    if (jerry_value_is_function(fail_func))
+    {
+        js_add_event_listener(js_target, "fail", fail_func);
+    }
+    jerry_release_value(fail_func);
+
+    jerry_value_t complete_func = js_get_property(requestObj, "complete");
+    if (jerry_value_is_function(complete_func))
+    {
+        js_add_event_listener(js_target, "complete", complete_func);
+    }
+    jerry_release_value(complete_func);
+}
+
+void reqeuset_get_config(request_config_t *config, jerry_value_t requestObj)
+{
+    /*get url*/
+    jerry_value_t js_url = js_get_property(requestObj, "url");
+    if (jerry_value_is_string(js_url))
+    {
+        config->url = js_value_to_string(js_url);
+    }
+    jerry_release_value(js_url);
+
+    /*get data*/
+    jerry_value_t js_data = js_get_property(requestObj, "data");
+    if (jerry_value_is_object(js_data))
+    {
+        jerry_value_t stringified = jerry_json_stringfy(js_data);
+        config->data = js_value_to_string(stringified);
+        jerry_release_value(stringified);
+    }
+    else if (jerry_value_is_string(js_data))
+    {
+        config->data = js_value_to_string(js_data);
+    }
+    jerry_release_value(js_data);
+
+    /*get header*/
+    config->session = webclient_session_create(HEADER_BUFSZ);;
+    jerry_value_t js_header = js_get_property(requestObj, "header");
+    request_get_header(config->session, js_header);
+    jerry_release_value(js_header);
+
+    /*get method*/
+    jerry_value_t method_value = js_get_property(requestObj, "method");
+    if (jerry_value_is_string(method_value))
+    {
+        char *method_str = js_value_to_string(method_value);
+        if (method_str)
+        {
+            if (strcmp(method_str, "POST") == 0)
+            {
+                config->method = WEBCLIENT_POST;
+            }
+            free(method_str);
+        }
+    }
+    jerry_release_value(method_value);
+}
+
+DECLARE_HANDLER(request)
+{
+    if (args_cnt != 1 || !jerry_value_is_object(args[0]))
+    {
+        return jerry_create_undefined();
+    }
+
+    jerry_value_t requestObj = args[0];
+    jerry_value_t rqObj = jerry_create_object();
+    js_make_emitter(rqObj, jerry_create_undefined());
+    struct js_callback *request_callback = js_add_callback(request_callback_func);
+    struct js_callback *close_callback = js_add_callback(request_callback_free);
+
+    requeset_add_event_listener(rqObj, requestObj);
+
+    request_config_t config;
+    config.method = WEBCLIENT_GET;
+    config.url = RT_NULL;
+    config.data = RT_NULL;
+    config.response = 0;
+    config.session = RT_NULL;
+
+    reqeuset_get_config(&config, requestObj);
+
+    if (config.session != RT_NULL && config.method == WEBCLIENT_GET)
+    {
+        config.response = webclient_get(config.session, config.url);
+    }
+    else if (config.session != RT_NULL && config.method == WEBCLIENT_POST)
+    {
+        webclient_header_fields_add(config.session, "Content-Length: %d\r\n", strlen(config.data));
+        webclient_header_fields_add(config.session, "Content-Type: application/octet-stream\r\n");
+        config.response = webclient_post(config.session, config.url, config.data);
+    }
+
+    free(config.data);
+    free(config.url);
+
+    request_tdinfo_t *rp = (request_tdinfo_t *)malloc(sizeof(request_tdinfo_t));
+    memset(rp, 0, sizeof(request_tdinfo_t));
+    rp->request_callback = request_callback;
+    rp->close_callback = close_callback;
+    rp->target_value = rqObj;
+    rp->session = config.session;
+
+    if (config.session == RT_NULL || config.response != 200)
+    {
+        //do fail callback
+        request_cbinfo_t *fail_info  = (request_cbinfo_t *)malloc(sizeof(request_cbinfo_t));
+        fail_info->target_value = rqObj;
+        fail_info->callback_name = rt_strdup("fail");
+        fail_info->return_value = RT_NULL;
+        fail_info->data_value = RT_NULL;
+
+        js_send_callback(request_callback, fail_info, sizeof(request_cbinfo_t));
+        free(fail_info);
+
+        //do complete callback
+        request_cbinfo_t *complete_info = (request_cbinfo_t *)malloc(sizeof(request_cbinfo_t));
+        complete_info->target_value = rqObj;
+        complete_info->callback_name = rt_strdup("complete");
+        complete_info->return_value = RT_NULL;
+        complete_info->data_value = RT_NULL;
+
+        js_send_callback(request_callback, complete_info, sizeof(request_cbinfo_t));
+        free(complete_info);
+
+        goto __exit;
+    }
+
+    rt_thread_t read_request = rt_thread_create("requestRead", request_read_entry, rp, 1536, 20, 5);
+    rt_thread_startup(read_request);
+    return jerry_acquire_value(rqObj);
+
+__exit:
+    js_send_callback(close_callback, rp, sizeof(request_tdinfo_t));
+    free(rp);
+    return jerry_create_undefined();
+}
+
+int jerry_request_init(jerry_value_t obj)
+{
+    REGISTER_METHOD(obj, request);
+    return 0;
+}
+
+static jerry_value_t _jerry_request_init()
+{
+    jerry_value_t js_requset = jerry_create_object();
+
+    REGISTER_METHOD_NAME(js_requset, "request", request);
+
+    return jerry_acquire_value(js_requset);
+}
+
+JS_MODULE(http, _jerry_request_init)
+#endif

+ 45 - 0
rtthread-port/jerry_request_init.h

@@ -0,0 +1,45 @@
+#ifndef JERRY_REQUEST_INIT_H__
+#define JERRY_REQUEST_INIT_H__
+
+#include <rtthread.h>
+
+#ifdef PKG_USING_WEBCLIENT
+
+#include <jerry_util.h>
+#include <jerry_event.h>
+#include <jerry_callbacks.h>
+#include <webclient.h>
+#include <jerry_buffer.h>
+
+#define READ_MAX_SIZE 50*1024
+#define HEADER_BUFSZ 1024
+
+struct request_callback_info
+{
+    jerry_value_t target_value;
+    jerry_value_t return_value;
+    jerry_value_t data_value;
+    char *callback_name;
+}typedef request_cbinfo_t;
+
+struct request_thread_info
+{
+    jerry_value_t target_value;
+    struct webclient_session *session;
+    struct js_callback *request_callback;
+    struct js_callback *close_callback;
+}typedef request_tdinfo_t;
+
+struct request_config_info{
+    char *url;
+    char *data;
+    struct webclient_session* session;
+    int method;
+    int response;
+}typedef request_config_t;
+
+int jerry_request_init(jerry_value_t obj);
+
+#endif
+
+#endif