//======================== int tcp_read(lua_State* L) { tcp_info_t* p = ((tcp_info_t*)luaL_checkudata(L, 1, LUA_TCP)); size_t size = luaL_checkinteger(L, 2); luaL_Buffer b; int nread; int i; int ret; char* buf = vm_malloc(size); if(buf == NULL) { return luaL_error(L, "malloc() failed"); } nread = vm_tcp_read(p->handle, buf, size); if(nread < 0) { ret = luaL_error(L, "tcp failed to read"); } else if(nread == 0) { // receives the FIN from the server ret = 0; } else { luaL_buffinit(L, &b); for(i = 0; i < size; i++) { luaL_addchar(&b, buf[i]); } luaL_pushresult(&b); ret = 1; } free(buf); return ret; }
boolean LTcpClient::wifiRead(void *userData) { LTcpReadWriteContext *pContext = (LTcpReadWriteContext*)userData; LTcpClient *pThis = pContext->pInst; pContext->lenProcessed = 0; // parameter check if(pContext->len <= 0) { return true; } vm_log_info("wifiRead len=%d", pContext->len); // check peek state if(pThis->m_peekBuffered) { // insert the peeked byte *((VMINT8*)pContext->buf) = pThis->m_peekByte; pContext->lenProcessed += 1; pContext->len--; // clear peek state pThis->m_peekByte = -1; pThis->m_peekBuffered = false; } VMINT readResult = VM_TCP_READ_EOF; // actually read from TCP socket if (pContext->serverHandle != -1) { readResult = vm_soc_svr_read(pContext->serverHandle, pContext->handle, pContext->buf, pContext->len); } else { readResult = vm_tcp_read(pContext->handle, pContext->buf, pContext->len); } if (readResult > 0) { pContext->lenProcessed += readResult; } if (readResult == VM_TCP_READ_EOF) { // we may cache a peek byte even if the socket is disconnected vm_log_info("wifiRead socket disconnected"); } vm_log_info("wifiRead %d bytes", pContext->lenProcessed); return true; }
//----------------------------------------------------------------------------------- static void __tcp_callback(VM_TCP_HANDLE handle, VM_TCP_EVENT event, void* user_data) { tcp_info_t* p = (tcp_info_t*)user_data; lua_State* L = p->L; lua_rawgeti(L, LUA_REGISTRYINDEX, p->cb_ref); if ((lua_type(L, -1) != LUA_TFUNCTION) && (lua_type(L, -1) != LUA_TLIGHTFUNCTION)) { // * BAD CB function reference lua_remove(L, -1); if (event == VM_TCP_EVENT_CAN_READ) { printf("[TCP] Read.\n"); int nread = -1; char buf[256]; while (nread > 0) { nread = vm_tcp_read(handle, buf, 254); if (nread < 0) { break; } else if (nread > 0) { buf[nread] = '\n'; buf[nread+1] = '\0'; printf("%s\n", buf); } } } else if (event == VM_TCP_EVENT_CONNECTED) { printf("[TCP] Connected.\n"); if (send_buf != NULL) { int nwrt = vm_tcp_write(handle, send_buf, strlen(send_buf)); printf("[TCP] Sent: %d\n", nwrt); } } else if (event == VM_TCP_EVENT_PIPE_CLOSED) { printf("[TCP] Closed.\n"); if (send_buf != NULL) { vm_free(send_buf); } } else printf("[TCP] Event: %d\n", event); } else { lua_pushlightuserdata(L, p); luaL_getmetatable(L, LUA_TCP); lua_setmetatable(L, -2); lua_pushinteger(L, (int)event); lua_call(L, 2, 0); } }
static void _vm_preload_read_data(vm_preload_ctx_t * ctx_p) { VMCHAR *body = (VMCHAR *)_vm_kernel_calloc(BUFFER_LEN); //VMCHAR http_buffer[BUFFER_LEN] = {0}; VMINT len = 0, i = 0; VMINT http_header_received = 0; VMINT first_downloaded = 0; VMINT http_header_len = 0; VMINT file_handle = -1; VMINT ret = 0; VMBYTE * buf = NULL; VMFILE f_handle = -1; VMUINT written = 0; vm_preload_recv_data_t data = {{E_PRELOAD_QUERYING, NULL}, 0, 0}; data.head.user_data = ctx_p->user_data; //memset(buf, 0, sizeof(2*BUFFER_LEN)); MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3358 , ctx_p->g_http_content_length); // read the header if (0 == ctx_p->g_http_content_length) { buf = (VMBYTE *)_vm_kernel_malloc(BUFFER_LEN); if (NULL == buf) { MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_PRELOAD_E1, 7, __LINE__); return; } memset(buf, 0, sizeof(BUFFER_LEN)); while ((ret = vm_tcp_read (ctx_p->soc_id, buf + len, BUFFER_LEN - len)) > 0) { len += ret; MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3369 , ret, len); } for(i = 1; i < len; i++) { if (buf[i] == LF && buf[i - 1] == CR) { if (app_strnicmp((kal_char *)&buf[http_header_len], (kal_char *)CONTENT_LENGTH, strlen(CONTENT_LENGTH)) == 0) { buf[i - 1] = '\0'; first_downloaded = 0; ctx_p->g_http_content_length = atoi((const char *)&buf[http_header_len] + strlen(CONTENT_LENGTH) + 1); ctx_p->need_recv_len = ctx_p->g_http_content_length; //data.total = http_content_length;I ctx_p->update = 1; } http_header_len = i + 1; if ((i + 2) < len && (buf[i + 2] == LF && buf[i + 1] == CR)) { http_header_len += 2; first_downloaded = len - http_header_len; break; } } } //strncpy(body, buf + 2, first_downloaded); memcpy(body, &buf[http_header_len], first_downloaded); _vm_kernel_free(buf); if (!vm_preload_is_url_valid(body, ctx_p, 0)) { _vm_preload_try_download(ctx_p); ctx_p->g_http_content_length = ctx_p->need_recv_len = 0; //ctx_p->update = 0; _vm_kernel_free(body); return; } // preparing file f_handle = vm_file_open(ctx_p->path, MODE_READ, 1); if (0 <= f_handle) { vm_file_close(f_handle); MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3411 ); vm_file_delete(ctx_p->path); } f_handle = vm_file_open(ctx_p->path, MODE_CREATE_ALWAYS_WRITE, 1); } // preparing file if (0 > f_handle) { f_handle = vm_file_open(ctx_p->path, MODE_APPEND, 1); } if (0 > f_handle) { VMCHAR buf[260]; vm_ucs2_to_ascii(buf, 260, ctx_p->path); MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3429 , buf); data.head.state = E_PRELOAD_ERR_PATH; ctx_p->status = E_PRELOAD_ERR_PATH; _vm_preload_clean_and_free_ctx(ctx_p, &data); _vm_kernel_free(body); return; } // no disk space { VMWCHAR drv_wname[4] = {0}; VMUINT size = 0; vm_wstrncpy(drv_wname, ctx_p->path, 1); size = vm_get_disk_free_space(drv_wname); if (size < (VMUINT)ctx_p->g_http_content_length) { MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3429 , (VMCHAR*)drv_wname); data.head.state = E_PRELOAD_FAILURE; ctx_p->status = E_PRELOAD_FAILURE; if (0 <= f_handle) { vm_file_close(f_handle); vm_file_delete(ctx_p->path); } _vm_preload_clean_and_free_ctx(ctx_p, &data); _vm_kernel_free(body); return; } } do { len = first_downloaded; while ((ret = vm_tcp_read (ctx_p->soc_id, body + len, (ctx_p->g_http_content_length > BUFFER_LEN ? BUFFER_LEN : ctx_p->g_http_content_length) - len)) > 0) { // would block if (0 == ret) { MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3448 ); break; } len += ret; if (BUFFER_LEN == len) { MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3454 ); break; } } ctx_p->g_http_content_length -= len; first_downloaded = 0; MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3462 , len); data.head.state = E_PRELOAD_DOWNLOADING; ctx_p->status = (VMINT)E_PRELOAD_DOWNLOADING; data.total = ctx_p->need_recv_len; data.received = ctx_p->need_recv_len - ctx_p->g_http_content_length; //data.buf = body; //data.size = len; MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3469 , data.received, data.total); MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3470 ); vm_file_write(f_handle, body, len, &written); PRELOAD_PMNG_WRAP_CALLBACK(ctx_p->p_hdl, ctx_p->cb, ctx_p->res_id, (void*)&data); } while (BUFFER_LEN == len && 0 != ret); // would block break vm_file_close(f_handle); if (0 == ctx_p->g_http_content_length) { data.head.state = E_PRELOAD_DOWNLOADED; ctx_p->status = (VMINT)E_PRELOAD_DOWNLOADED; data.total = ctx_p->g_http_content_length; MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3485 , data.total); MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3486 ); _vm_preload_clean_and_free_ctx(ctx_p, &data); } #if 0 /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ #endif _vm_kernel_free(body); MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3582 ); }
static void _vm_preload_read_address(vm_preload_ctx_t * ctx_p) { //VMCHAR http_header[BUFFER_LEN*2] = {0}; //VMCHAR http_buffer[BUFFER_LEN] = {0}; static VMINT len = 0; static VMINT wblock = 0; VMINT i = 0, j = 0; VMINT http_header_received = 0; VMINT http_content_downloaded = 0; VMINT http_content_length = 0; VMINT http_header_len = 0; VMINT file_handle = -1; VMINT ret = 0; VMINT feed_back = 0; VMBYTE * http_header = NULL; static VMBYTE * buf = NULL; vm_common_t head = {E_PRELOAD_QUERYING, NULL}; const VMCHAR * http_ver = "HTTP/1.1 "; VMINT location_len = 0; VMCHAR * Location = NULL; // read block if (!wblock) { buf = (VMBYTE *)_vm_kernel_malloc(2*BUFFER_LEN); if (NULL == buf) { MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_PRELOAD_E1, 5, __LINE__); return; } memset(buf, 0, sizeof(2*BUFFER_LEN)); } MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3223 ); while ((ret = vm_tcp_read (ctx_p->soc_id, buf + len, 2*BUFFER_LEN - len)) > 0) { len += ret; MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3227 , ret, len); } // read block http_header = _vm_kernel_malloc(BUFFER_LEN); if (NULL == http_header) { _vm_kernel_free(buf); MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_PRELOAD_E1, 6, __LINE__); return; } memset(http_header, 0, sizeof(BUFFER_LEN)); for(i = 0; i < len; i++) { http_header[http_header_len++] = buf[i]; if (http_header_len >= 2) { if (http_header[http_header_len - 1] == LF && http_header[http_header_len - 2] == CR) { if (http_header_len == 2) // 2 { http_content_downloaded += len - i - 1; j = i + 1; //data.received += len - i - 1; break; } else // 1 { http_header_len = 0; if (app_strnicmp((kal_char *)http_header, (kal_char *)CONTENT_LENGTH, strlen(CONTENT_LENGTH)) == 0) { //http_header[http_header_len - 2] = '\0'; http_content_downloaded = 0; http_content_length = atoi((const char *)http_header + strlen(CONTENT_LENGTH) + 1); } if (0 == app_strnicmp((kal_char*)http_header, (kal_char*)http_ver, strlen(http_ver))) { feed_back = atoi((const char *)http_header + strlen(http_ver)); } if (0 == app_strnicmp(http_header, "Location: ", strlen("Location: "))) { Location = _vm_kernel_malloc(BUFFER_LEN); memset(Location, 0, BUFFER_LEN); strcpy(Location, http_header + strlen("Location: ")); MMI_PRINT(MOD_MRE, MMI_MRE_TRC_MOD_VMSOCK,"preload 302/301Loc[%s]", Location); while (location_len < BUFFER_LEN) { if (Location[location_len + 1] == LF && Location[location_len] == CR) { break; } ++location_len; } //http_header_len = location_len; MMI_PRINT(MOD_MRE, MMI_MRE_TRC_MOD_VMSOCK,"preload 302/301 Loc len[%d]", location_len); } } } } } MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3264 , http_content_length, feed_back); // read block if (http_content_length > http_content_downloaded) { // recveived partitial data. wblock = 1; //_vm_preload_read_address(ctx_p); _vm_kernel_free(http_header); MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3227 , -2, len); return; } else // not read block { wblock = 0; len = 0; } //if (200 == feed_back) { // judge whether the url belong to the g-mobi(some times operator will rsp to client fristly when with wap. buf[j + http_content_length] = 0; MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3284 , buf + j); if (vm_preload_is_url_valid((const VMCHAR *)buf + j, ctx_p, 1))//if (0 == strstr(buf + j, "go href")) // confirm the data form server. { //VMINT pos = 0, ctx_len = http_content_downloaded < http_content_length ? http_content_downloaded - 1 : http_content_length; //while (0 != *(buf + j + pos) && pos < ctx_len) //{ // if (*(buf + j + pos) == '\r' && *(buf + j + pos + 1) == '\n') // break; // pos++; //} //*(buf + j + pos) = 0; ctx_p->twice_confirmed = 1; MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3287 ); // unexpected in response in body feed_back = vm_preload_get_feedback(buf + j, feed_back); MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3287 ); if (200 == feed_back && 0 < http_content_length) ctx_p->update = 1; if (302 == feed_back || 301 == feed_back) { memset(ctx_p->url, 0, sizeof(ctx_p->url)); memcpy(ctx_p->url, Location, location_len); ctx_p->query_info.ua[0] = 0; MMI_PRINT(MOD_MRE, MMI_MRE_TRC_MOD_VMSOCK,"preload 302/301[%s]", ctx_p->url); _vm_preload_try_query(ctx_p); _vm_kernel_free(http_header); _vm_kernel_free(buf); _vm_kernel_free(Location); return; } } } if (ctx_p->update) { strncpy((char*)ctx_p->url, (const char*)buf + j, http_content_length); //strcpy(ctx_p->url, buf + 2); MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3297 ); head.state = E_PRELOAD_AVAILABLE_UPDATE; if (ctx_p->soc_id > 0) { vm_tcp_close(ctx_p->soc_id); ctx_p->soc_id = -1; } } else { head.state = E_PRELOAD_NO_UPDATE; ctx_p->status = (VMINT)E_PRELOAD_NO_UPDATE; if (0 == ctx_p->twice_confirmed) { _vm_preload_try_query(ctx_p); ctx_p->twice_confirmed = 1; _vm_kernel_free(buf); _vm_kernel_free(http_header); return; } MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3318 ); head.user_data = ctx_p->user_data; _vm_preload_clean_and_free_ctx(ctx_p, &head); _vm_kernel_free(buf); _vm_kernel_free(http_header); return; } MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_PRELOAD_LOG, 4, __LINE__, ctx_p->update, head.state, ctx_p->res_id, ctx_p->user_data, ctx_p->cb, 0 ); head.user_data = ctx_p->user_data; PRELOAD_PMNG_WRAP_CALLBACK(ctx_p->p_hdl, ctx_p->cb, ctx_p->res_id, (void*)&head); if (1 == ctx_p->update) ctx_p->cb = NULL; else if (2 == ctx_p->update) ctx_p->update = 1; // recover it _vm_kernel_free(buf); _vm_kernel_free(http_header); MMI_TRACE(MMI_MRE_TRC_MOD_VMSOCK, TRC_MRE_VMSOCK_3335 ); }