//---------------------------------------------------------------------------------------------- static void _micoNotify_WiFi_Scan_OK (ScanResult_adv *pApList, mico_Context_t * const inContext) { (void)inContext; queue_msg_t msg; msg.L = gL; msg.source = onWIFI | 0x10; msg.para1 = pApList->ApNum; msg.para2 = wifi_scan_succeed; msg.para4 = NULL; if (pApList->ApNum > 0) { msg.para3 = (uint8_t*)malloc(sizeof(_ApList)*pApList->ApNum); if (msg.para3 != NULL) { memcpy((_ApList*)msg.para3, pApList->ApList, sizeof(_ApList)*pApList->ApNum); } else msg.para3 = NULL; } else msg.para3 = NULL; if (wifi_scan_succeed != LUA_NOREF) { mico_rtos_push_to_queue( &os_queue, &msg, 0); } else { _WiFi_Scan_OK(gL, msg.para1, (_ApList*)msg.para3, wifi_scanned_print); free(msg.para3); msg.para3 = NULL; } wifi_scanned = 1; }
static void timed_event_handler( void* arg ) { mico_timed_event_t* event_object = (mico_timed_event_t*) arg; mico_event_message_t message; message.function = event_object->function; message.arg = event_object->arg; mico_rtos_push_to_queue( &event_object->thread->event_queue, &message, MICO_NO_WAIT ); }
OSStatus mico_rtos_send_asynchronous_event( mico_worker_thread_t* worker_thread, event_handler_t function, void* arg ) { mico_event_message_t message; if( worker_thread->thread == NULL ) return kNotInitializedErr; message.function = function; message.arg = arg; return mico_rtos_push_to_queue( &worker_thread->event_queue, &message, MICO_NO_WAIT ); }
// == Timer interrupt handler ======= static void _tmr_handler( void* arg ) { unsigned id = (unsigned)arg; if(id<NUM_TMR) { queue_msg_t msg; msg.L = gL; msg.source = onTMR; //msg.para1 = tmr_cb_ref[id]; msg.para2 = tmr_cb_ref[id]; mico_rtos_push_to_queue( &os_queue, &msg,0); } }
//------------------------------------------------------------------------------------------ static void _micoNotify_WifiStatusHandler(WiFiEvent event, mico_Context_t * const inContext) { (void)inContext; queue_msg_t msg; msg.L = gL; msg.source = onWIFI; msg.para3 = NULL; msg.para4 = NULL; switch (event) { case NOTIFY_STATION_UP: wifi_sta_started = 1; if (wifi_status_changed_STA != LUA_NOREF) { msg.para1 = 0; msg.para2 = wifi_status_changed_STA; mico_rtos_push_to_queue( &os_queue, &msg, 0); } break; case NOTIFY_STATION_DOWN: wifi_sta_started = 0; if (wifi_status_changed_STA != LUA_NOREF) { msg.para1 = 1; msg.para2 = wifi_status_changed_STA; mico_rtos_push_to_queue( &os_queue, &msg, 0); } break; case NOTIFY_AP_UP: wifi_ap_started = 1; if (wifi_status_changed_AP != LUA_NOREF) { msg.para1 = 2; msg.para2 = wifi_status_changed_AP; mico_rtos_push_to_queue( &os_queue, &msg, 0); } break; case NOTIFY_AP_DOWN: wifi_ap_started = 0; if (wifi_status_changed_AP != LUA_NOREF) { msg.para1 = 3; msg.para2 = wifi_status_changed_AP; mico_rtos_push_to_queue( &os_queue, &msg, 0); } break; default: if (wifi_status_changed_AP != LUA_NOREF) { msg.para1 = 4; msg.para2 = wifi_status_changed_AP; mico_rtos_push_to_queue( &os_queue, &msg, 0); } if (wifi_status_changed_STA != LUA_NOREF) { msg.para1 = 4; msg.para2 = wifi_status_changed_STA; mico_rtos_push_to_queue( &os_queue, &msg, 0); } break; } }
OSStatus SysComSendMsg(SysComMsg *msg) { OSStatus err = kUnknownErr; mico_rtos_lock_mutex(&SysComMutex); err = mico_rtos_push_to_queue(&SysComQueue[msg->receiver], &msg, 0); if(err != kNoErr) { SysCom_ERR("SysComSend: msg(addr: 0x%08X) push to SysComQueue[%d] failed with err(%d)", (addP_t)msg, msg->receiver, err); } else { SysCom_DBG("SysComSend: msg(addr: 0x%08X) push to SysComQueue[%d] successfully", (addP_t)msg, msg->receiver); } mico_rtos_unlock_mutex(&SysComMutex); return err; }
OSStatus sppUartCommandProcess(uint8_t *inBuf, int inLen, app_context_t * const inContext) { spp_log_trace(); OSStatus err = kNoErr; int i; mico_queue_t* p_queue=NULL; socket_msg_t *real_msg; for(i=0; i < MAX_QUEUE_NUM; i++) { p_queue = inContext->appStatus.socket_out_queue[i]; if(p_queue != NULL ){ break; } } if (p_queue == NULL) return kNoErr; if (MAX_SOCK_MSG_LEN < sockmsg_len) return kNoMemoryErr; real_msg = (socket_msg_t*)malloc(sizeof(socket_msg_t) - 1 + inLen); if (real_msg == NULL) return kNoMemoryErr; sockmsg_len += (sizeof(socket_msg_t) - 1 + inLen); real_msg->len = inLen; memcpy(real_msg->data, inBuf, inLen); real_msg->ref = 0; mico_rtos_lock_mutex(&inContext->appStatus.queue_mtx); socket_msg_take(real_msg); for(i=0; i < MAX_QUEUE_NUM; i++) { p_queue = inContext->appStatus.socket_out_queue[i]; if(p_queue != NULL ){ socket_msg_take(real_msg); if (kNoErr != mico_rtos_push_to_queue(p_queue, &real_msg, 0)) { socket_msg_free(real_msg); } } } socket_msg_free(real_msg); mico_rtos_unlock_mutex(&inContext->appStatus.queue_mtx); return err; }
OSStatus AaSysComSend(void* msg_ptr) { if(msg_ptr == NULL) { AaSysLogPrint(LOGLEVEL_ERR, "msg_ptr is NULL"); return kParamErr; } SMsgInternalHeader header; SMsgHeader* msg = (SMsgHeader*)msg_ptr; if(msg->sender >= MsgQueue_MAX || msg->target >= MsgQueue_MAX) { AaSysLogPrint(LOGLEVEL_ERR, "sender 0x%02x or receiver 0x%02x failed", msg->sender, msg->target); return kParamErr; } if(msg->msg_id >= API_MESSAGE_ID_MAX) { AaSysLogPrint(LOGLEVEL_ERR, "message id 0x%04x failed", msg->msg_id); return kParamErr; } header.msg_id = msg->msg_id; header.target = msg->target; header.sender = msg->sender; header.body_size = sizeof(SMsgHeader) + msg->pl_size; header.body = msg_ptr; if(kNoErr != mico_rtos_push_to_queue(&msg_queue[header.target], &header, MICO_WAIT_FOREVER)) { AaSysLogPrint(LOGLEVEL_ERR, "message 0x%04x send failed", header.msg_id); if(msg_ptr != NULL) free(msg_ptr); return kInProgressErr; } AaSysLogPrint(LOGLEVEL_DBG, "message(0x%04x) have been sent from %s to %s", header.msg_id, AaSysComPrintThreadName(header.sender), AaSysComPrintThreadName(header.target)); return kNoErr; }
//=================================== static int queue_push( lua_State* L ) { if (lua_type(L, 1) == LUA_TFUNCTION || lua_type(L, 1) == LUA_TLIGHTFUNCTION) { lua_pushvalue(L, 1); // copy argument (func) to the top of stack gL = L; queue_msg_t msg; msg.L = gL; msg.source = USER; if (lua_type(L, 2) == LUA_TNUMBER) msg.para1 = luaL_checkinteger( L, 2 ); else msg.para1 = -9999; msg.para2 = luaL_ref(L, LUA_REGISTRYINDEX); mico_rtos_push_to_queue( &os_queue, &msg, 0); l_message( NULL, "pushed"); } else return luaL_error( L, "callback function needed" ); return 0; }
// handle cloud msg here, for example: send to USART or echo to cloud OSStatus MicoFogCloudCloudMsgProcess(mico_Context_t* context, const char* topic, const unsigned int topicLen, unsigned char *inBuf, unsigned int inBufLen) { fogcloud_log_trace(); OSStatus err = kUnknownErr; uint32_t real_msg_len = 0; // push msg into queue fogcloud_msg_t *real_msg; fogcloud_msg_t *p_tem_msg = NULL; // msg pointer real_msg_len = sizeof(fogcloud_msg_t) + topicLen + inBufLen; if(FOGCLOUD_TOTAL_BUF_LENGTH < (total_recv_buf_len + real_msg_len)){ return kNoMemoryErr; } real_msg = (fogcloud_msg_t*)malloc(real_msg_len); if (real_msg == NULL){ return kNoMemoryErr; } total_recv_buf_len += real_msg_len; memset(real_msg, '\0', sizeof(real_msg)); real_msg->topic_len = topicLen; real_msg->data_len = inBufLen; memcpy(real_msg->data, topic, topicLen); memcpy(real_msg->data + topicLen, inBuf, inBufLen); //memcpy(real_msg->data + topicLen + inBufLen, '\0', 1); if(NULL != msg_recv_queue){ mico_rtos_lock_mutex(&msg_recv_queue_mutex); if(mico_rtos_is_queue_full(&msg_recv_queue)){ fogcloud_log("WARNGING: FogCloud msg overrun, abandon old messages!"); err = mico_rtos_pop_from_queue(&msg_recv_queue, &p_tem_msg, 0); // just pop old msg pointer from queue if(kNoErr == err){ if(NULL != p_tem_msg){ // delete msg, free msg memory free(p_tem_msg); p_tem_msg = NULL; } } else{ mico_rtos_unlock_mutex(&msg_recv_queue_mutex); fogcloud_log("WARNGING: FogCloud msg overrun, abandon current message!"); if(NULL != real_msg){ // queue full, new msg abandoned free(real_msg); real_msg = NULL; } return kOverrunErr; } } // insert a msg into recv queue if (kNoErr != mico_rtos_push_to_queue(&msg_recv_queue, &real_msg, 0)) { // just push msg pointer in queue free(real_msg); real_msg = NULL; err = kWriteErr; } else{ err = kNoErr; } mico_rtos_unlock_mutex(&msg_recv_queue_mutex); } else{ if(NULL != real_msg){ free(real_msg); real_msg = NULL; } return kNotInitializedErr; } return err; }
/** * @brief USBH_MSC_BOT_Process * The function handle the BOT protocol. * @param phost: Host handle * @param lun: Logical Unit Number * @retval USBH Status */ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun) { USBH_StatusTypeDef status = USBH_BUSY; USBH_StatusTypeDef error = USBH_BUSY; BOT_CSWStatusTypeDef CSW_Status = BOT_CSW_CMD_FAILED; USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE; MSC_HandleTypeDef *MSC_Handle = phost->pActiveClass->pData; uint8_t toggle = 0; uint16_t USBH_URB = USBH_URB_EVENT; switch (MSC_Handle->hbot.state) { case BOT_SEND_CBW: MSC_Handle->hbot.cbw.field.LUN = lun; MSC_Handle->hbot.state = BOT_SEND_CBW_WAIT; USBH_BulkSendData (phost, MSC_Handle->hbot.cbw.data, BOT_CBW_LENGTH, MSC_Handle->OutPipe, 1); break; case BOT_SEND_CBW_WAIT: URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->OutPipe); if(URB_Status == USBH_URB_DONE) { if ( MSC_Handle->hbot.cbw.field.DataTransferLength != 0 ) { /* If there is Data Transfer Stage */ if (((MSC_Handle->hbot.cbw.field.Flags) & USB_REQ_DIR_MASK) == USB_D2H) { /* Data Direction is IN */ MSC_Handle->hbot.state = BOT_DATA_IN; } else { /* Data Direction is OUT */ MSC_Handle->hbot.state = BOT_DATA_OUT; } } else { /* If there is NO Data Transfer Stage */ MSC_Handle->hbot.state = BOT_RECEIVE_CSW; } #if (USBH_USE_OS == 1) mico_rtos_push_to_queue((mico_queue_t *) &(phost->os_event), &USBH_URB, 0 ); #endif } else if(URB_Status == USBH_URB_NOTREADY) { /* Re-send CBW */ MSC_Handle->hbot.state = BOT_SEND_CBW; #if (USBH_USE_OS == 1) mico_rtos_push_to_queue((mico_queue_t *) &(phost->os_event), &USBH_URB, 0 ); #endif } else if(URB_Status == USBH_URB_STALL) { MSC_Handle->hbot.state = BOT_ERROR_OUT; #if (USBH_USE_OS == 1) mico_rtos_push_to_queue((mico_queue_t *) &(phost->os_event), &USBH_URB, 0 ); #endif } break; case BOT_DATA_IN: /* Send first packet */ USBH_BulkReceiveData (phost, MSC_Handle->hbot.pbuf, MSC_Handle->InEpSize , MSC_Handle->InPipe); MSC_Handle->hbot.state = BOT_DATA_IN_WAIT; break; case BOT_DATA_IN_WAIT: URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->InPipe); if(URB_Status == USBH_URB_DONE) { /* Adjudt Data pointer and data length */ if(MSC_Handle->hbot.cbw.field.DataTransferLength > MSC_Handle->InEpSize) { MSC_Handle->hbot.pbuf += MSC_Handle->InEpSize; MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->InEpSize; } else { MSC_Handle->hbot.cbw.field.DataTransferLength = 0; } /* More Data To be Received */ if(MSC_Handle->hbot.cbw.field.DataTransferLength > 0) { /* Send next packet */ USBH_BulkReceiveData (phost, MSC_Handle->hbot.pbuf, MSC_Handle->InEpSize , MSC_Handle->InPipe); } else { /* If value was 0, and successful transfer, then change the state */ MSC_Handle->hbot.state = BOT_RECEIVE_CSW; #if (USBH_USE_OS == 1) mico_rtos_push_to_queue((mico_queue_t *) &(phost->os_event), &USBH_URB, 0 ); #endif } } else if(URB_Status == USBH_URB_STALL) { /* This is Data IN Stage STALL Condition */ MSC_Handle->hbot.state = BOT_ERROR_IN; /* Refer to USB Mass-Storage Class : BOT (www.usb.org) 6.7.2 Host expects to receive data from the device 3. On a STALL condition receiving data, then: The host shall accept the data received. The host shall clear the Bulk-In pipe. 4. The host shall attempt to receive a CSW.*/ #if (USBH_USE_OS == 1) mico_rtos_push_to_queue((mico_queue_t *) &(phost->os_event), &USBH_URB, 0 ); #endif } break; case BOT_DATA_OUT: USBH_BulkSendData (phost, MSC_Handle->hbot.pbuf, MSC_Handle->OutEpSize , MSC_Handle->OutPipe, 1); MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT; break; case BOT_DATA_OUT_WAIT: URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->OutPipe); if(URB_Status == USBH_URB_DONE) { /* Adjudt Data pointer and data length */ if(MSC_Handle->hbot.cbw.field.DataTransferLength > MSC_Handle->OutEpSize) { MSC_Handle->hbot.pbuf += MSC_Handle->OutEpSize; MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->OutEpSize; } else { MSC_Handle->hbot.cbw.field.DataTransferLength = 0; } /* More Data To be Sent */ if(MSC_Handle->hbot.cbw.field.DataTransferLength > 0) { USBH_BulkSendData (phost, MSC_Handle->hbot.pbuf, MSC_Handle->OutEpSize , MSC_Handle->OutPipe, 1); } else { /* If value was 0, and successful transfer, then change the state */ MSC_Handle->hbot.state = BOT_RECEIVE_CSW; } #if (USBH_USE_OS == 1) mico_rtos_push_to_queue((mico_queue_t *) &(phost->os_event), &USBH_URB, 0 ); #endif } else if(URB_Status == USBH_URB_NOTREADY) { /* Re-send same data */ MSC_Handle->hbot.state = BOT_DATA_OUT; #if (USBH_USE_OS == 1) mico_rtos_push_to_queue((mico_queue_t *) &(phost->os_event), &USBH_URB, 0 ); #endif } else if(URB_Status == USBH_URB_STALL) { MSC_Handle->hbot.state = BOT_ERROR_OUT; /* Refer to USB Mass-Storage Class : BOT (www.usb.org) 6.7.3 Ho - Host expects to send data to the device 3. On a STALL condition sending data, then: " The host shall clear the Bulk-Out pipe. 4. The host shall attempt to receive a CSW. */ #if (USBH_USE_OS == 1) mico_rtos_push_to_queue((mico_queue_t *) &(phost->os_event), &USBH_URB, 0 ); #endif } break; case BOT_RECEIVE_CSW: USBH_BulkReceiveData (phost, MSC_Handle->hbot.csw.data, BOT_CSW_LENGTH , MSC_Handle->InPipe); MSC_Handle->hbot.state = BOT_RECEIVE_CSW_WAIT; break; case BOT_RECEIVE_CSW_WAIT: URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->InPipe); /* Decode CSW */ if(URB_Status == USBH_URB_DONE) { MSC_Handle->hbot.state = BOT_SEND_CBW; MSC_Handle->hbot.cmd_state = BOT_CMD_SEND; CSW_Status = USBH_MSC_DecodeCSW(phost); if(CSW_Status == BOT_CSW_CMD_PASSED) { status = USBH_OK; } else { status = USBH_FAIL; } #if (USBH_USE_OS == 1) mico_rtos_push_to_queue((mico_queue_t *) &(phost->os_event), &USBH_URB, 0 ); #endif } else if(URB_Status == USBH_URB_STALL) { MSC_Handle->hbot.state = BOT_ERROR_IN; #if (USBH_USE_OS == 1) mico_rtos_push_to_queue((mico_queue_t *) &(phost->os_event), &USBH_URB, 0 ); #endif } break; case BOT_ERROR_IN: error = USBH_MSC_BOT_Abort(phost, lun, BOT_DIR_IN); if (error == USBH_OK) { MSC_Handle->hbot.state = BOT_RECEIVE_CSW; } else if (error == USBH_UNRECOVERED_ERROR) { /* This means that there is a STALL Error limit, Do Reset Recovery */ MSC_Handle->hbot.state = BOT_UNRECOVERED_ERROR; } break; case BOT_ERROR_OUT: error = USBH_MSC_BOT_Abort(phost, lun, BOT_DIR_OUT); if ( error == USBH_OK) { toggle = USBH_LL_GetToggle(phost, MSC_Handle->OutPipe); USBH_LL_SetToggle(phost, MSC_Handle->OutPipe, 1- toggle); USBH_LL_SetToggle(phost, MSC_Handle->InPipe, 0); MSC_Handle->hbot.state = BOT_ERROR_IN; } else if (error == USBH_UNRECOVERED_ERROR) { MSC_Handle->hbot.state = BOT_UNRECOVERED_ERROR; } break; case BOT_UNRECOVERED_ERROR: status = USBH_MSC_BOT_REQ_Reset(phost); if ( status == USBH_OK) { MSC_Handle->hbot.state = BOT_SEND_CBW; } break; default: break; } return status; }
// ======= FTP thread handler ========= static void _thread_ftp(void*inContext) { (void)inContext; fd_set readset, wrset; struct timeval_t t_val; int k; uint32_t timeout = 0; uint8_t recv_tmo = 0; t_val.tv_sec = 0; t_val.tv_usec = 5000; timeout = mico_get_time(); ftp_log("\r\n[FTP trd] FTP THREAD STARTED\r\n"); // *** First we have to get IP address and connect the cmd socket char pIPstr[16]={0}; int err; k = 3; do { err = gethostbyname((char *)pDomain4Dns, (uint8_t *)pIPstr, 16); if (err != kNoErr) { k--; mico_thread_msleep(50); } }while ((err != kNoErr) && (k > 0)); if ((err == kNoErr) && (ftpCmdSocket != NULL)) { ftpCmdSocket->addr.s_ip = inet_addr(pIPstr); ftpCmdSocket->clientFlag = NO_ACTION; free(pDomain4Dns); pDomain4Dns=NULL; // Connect socket! char ip[17]; memset(ip, 0x00, 17); inet_ntoa(ip, ftpCmdSocket->addr.s_ip); ftp_log("[FTP cmd] Got IP: %s, connecting...\r\n", ip); struct sockaddr_t *paddr = &(ftpCmdSocket->addr); int slen = sizeof(ftpCmdSocket->addr); // _micoNotify will be called if connected connect(ftpCmdSocket->socket, paddr, slen); } else { ftp_log("[FTP dns] Get IP error\r\n"); goto terminate; } if (recvBuf == NULL) { recvBuf = malloc(MAX_RECV_LEN+4); memset(recvBuf, 0, MAX_RECV_LEN+4); } recvLen = 0; // =========================================================================== // Main Thread loop while (1) { mico_thread_msleep(5); if (ftpCmdSocket == NULL) goto terminate; if ( ((mico_get_time() - timeout) > MAX_FTP_TIMEOUT) || (((mico_get_time() - timeout) > 8000) && (!(status & FTP_LOGGED))) ) { // ** TIMEOUT ** ftp_log("[FTP trd] Timeout\r\n"); timeout = mico_get_time(); if ((status & FTP_LOGGED)) ftpCmdSocket->clientFlag = REQ_ACTION_QUIT; else ftpCmdSocket->clientFlag = REQ_ACTION_DISCONNECT; } // ========== stage #1, Check cmd socket action requests =================== //REQ_ACTION_DISCONNECT if (ftpCmdSocket->clientFlag == REQ_ACTION_DISCONNECT) { ftpCmdSocket->clientFlag = NO_ACTION; closeDataSocket(); ftp_log("[FTP cmd] Socket disconnected\r\n"); if (ftpCmdSocket->disconnect_cb != LUA_NOREF) { queue_msg_t msg; msg.L = gL; msg.source = onFTP; msg.para1 = 0; msg.para2 = ftpCmdSocket->disconnect_cb; mico_rtos_push_to_queue( &os_queue, &msg, 0); } closeCmdSocket(0); continue; } //REQ_ACTION_QUIT if (ftpCmdSocket->clientFlag == REQ_ACTION_QUIT) { if ((status & FTP_LOGGED)) { ftpCmdSocket->clientFlag = NO_ACTION; ftp_log("[FTP cmd] Quit command\r\n"); if (_send("QUIT\r\n", 6) <= 0) { ftpCmdSocket->clientFlag = REQ_ACTION_DISCONNECT; } } else ftpCmdSocket->clientFlag = REQ_ACTION_DISCONNECT; continue; } if (!(status & FTP_CONNECTED)) continue; //-------------------------------------- //REQ_ACTION_LIST, REQ_ACTION_RECV, REQ_ACTION_SEND else if ((ftpCmdSocket->clientFlag == REQ_ACTION_LIST) || (ftpCmdSocket->clientFlag == REQ_ACTION_RECV) || (ftpCmdSocket->clientFlag == REQ_ACTION_SEND)) { ftpCmdSocket->clientLastFlag = ftpCmdSocket->clientFlag; ftpCmdSocket->clientFlag = NO_ACTION; _send("PASV\r\n", 6); } //REQ_ACTION_DOLIST else if (ftpCmdSocket->clientFlag == REQ_ACTION_DOLIST) { ftpCmdSocket->clientFlag = NO_ACTION; int res; if (ftpfile != NULL) { char tmps[100]; if (list_type == 1) sprintf(tmps,"NLST %s\r\n", ftpfile); else sprintf(tmps,"LIST %s\r\n", ftpfile); res = _send(&tmps[0], strlen(ftpfile)+7); free(ftpfile); ftpfile = NULL; } else { if (list_type == 1) res = _send("NLST\r\n", 6); else res = _send("LIST\r\n", 6); } if (res > 0) status |= FTP_LISTING; else { ftp_log("[FTP cmd] LIST command failed.\r\n"); } } //REQ_ACTION_DORECV else if (ftpCmdSocket->clientFlag == REQ_ACTION_DORECV) { ftpCmdSocket->clientFlag = NO_ACTION; char tmps[100]; sprintf(tmps,"RETR %s\r\n", ftpfile); int res = _send(&tmps[0], strlen(ftpfile)+7); if (res > 0) { status |= FTP_RECEIVING; file_status = 0; } else { ftp_log("[FTP cmd] RETR command failed.\r\n"); file_status = -4; } } //REQ_ACTION_DOSEND else if (ftpCmdSocket->clientFlag == REQ_ACTION_DOSEND) { ftpCmdSocket->clientFlag = NO_ACTION; char tmps[100]; if ((send_type & SEND_APPEND)) sprintf(tmps,"APPE %s\r\n", ftpfile); else sprintf(tmps,"STOR %s\r\n", ftpfile); int res = _send(&tmps[0], strlen(ftpfile)+7); if (res > 0) { file_status = 0; } else { ftp_log("[FTP cmd] STOR/APPE command failed.\r\n"); file_status = -4; } } //REQ_ACTION_CHDIR else if (ftpCmdSocket->clientFlag == REQ_ACTION_CHDIR) { ftpCmdSocket->clientFlag = NO_ACTION; if (ftpfile != NULL) { char tmps[100]; sprintf(tmps,"CWD %s\r\n", ftpfile); _send(&tmps[0], strlen(ftpfile)+6); free(ftpfile); ftpfile = NULL; } else { _send("PWD\r\n", 5); } } //REQ_ACTION_LOGGED else if (ftpCmdSocket->clientFlag == REQ_ACTION_LOGGED) { ftpCmdSocket->clientFlag=NO_ACTION; if (ftpCmdSocket->logon_cb != LUA_NOREF) { queue_msg_t msg; msg.L = gL; msg.source = onFTP; msg.para1 = 1; msg.para3 = NULL; msg.para2 = ftpCmdSocket->logon_cb; mico_rtos_push_to_queue( &os_queue, &msg, 0); } } //REQ_ACTION_LIST_RECEIVED else if (ftpCmdSocket->clientFlag == REQ_ACTION_LIST_RECEIVED) { ftpCmdSocket->clientFlag=NO_ACTION; if (ftpCmdSocket->list_cb != LUA_NOREF) { queue_msg_t msg; msg.L = gL; msg.source = onFTP; msg.para1 = recvDataLen; msg.para2 = ftpCmdSocket->list_cb; msg.para3 = (uint8_t*)malloc(recvDataLen+4); if (msg.para3 != NULL) memcpy((char*)msg.para3, recvDataBuf, recvDataLen); mico_rtos_push_to_queue( &os_queue, &msg, 0); } } //REQ_ACTION_RECEIVED else if (ftpCmdSocket->clientFlag == REQ_ACTION_RECEIVED) { ftpCmdSocket->clientFlag=NO_ACTION; if (ftpCmdSocket->received_cb != LUA_NOREF) { queue_msg_t msg; msg.L = gL; msg.source = onFTP; msg.para1 = file_status; msg.para3 = NULL; if (recv_type == RECV_TOSTRING) { msg.para3 = (uint8_t*)malloc(recvDataLen+4); if (msg.para3 != NULL) memcpy((char*)msg.para3, recvDataBuf, recvDataLen); } msg.para2 = ftpCmdSocket->received_cb; mico_rtos_push_to_queue( &os_queue, &msg, 0); } } //REQ_ACTION_SENT else if (ftpCmdSocket->clientFlag == REQ_ACTION_SENT) { ftpCmdSocket->clientFlag=NO_ACTION; if (ftpCmdSocket->sent_cb != LUA_NOREF) { queue_msg_t msg; msg.L = gL; msg.source = onFTP; msg.para1 = file_status; msg.para3 = NULL; msg.para2 = ftpCmdSocket->sent_cb; mico_rtos_push_to_queue( &os_queue, &msg, 0); } } // ========== stage 2, check data send ===================================== if ((ftpDataSocket != NULL) && ((status & FTP_SENDING))) { FD_ZERO(&wrset); FD_SET(ftpDataSocket->socket, &wrset); // check socket state select(ftpDataSocket->socket+1, NULL, &wrset, NULL, &t_val); if (FD_ISSET(ftpDataSocket->socket, &wrset)) { int err; if ((send_type & SEND_STRING)) err = _sendString(); else err = _sendFile(); if (err != 0) { closeDataSocket(); // close file; if (file_fd != FILE_NOT_OPENED) { SPIFFS_close(&fs,file_fd); file_fd = FILE_NOT_OPENED; ftp_log("\r\n[FTP dta] Data file closed\r\n"); } data_done = 1; status &= ~FTP_SENDING; ftpCmdSocket->clientFlag = REQ_ACTION_SENT; } continue; } } // ========== stage 3, check receive&disconnect ============================ FD_ZERO(&readset); // ** select sockets to monitor for receive or disconnect int maxfd = ftpCmdSocket->socket; FD_SET(ftpCmdSocket->socket, &readset); if ( (ftpDataSocket != NULL) && ((status & FTP_DATACONNECTED)) ) { if (ftpDataSocket->socket > maxfd) maxfd = ftpDataSocket->socket; FD_SET(ftpDataSocket->socket, &readset); } // ** check sockets state select(maxfd+1, &readset, NULL, NULL, &t_val); // ** Check COMMAND socket if (FD_ISSET(ftpCmdSocket->socket, &readset)) { // read received data to buffer int rcv_len; if ((MAX_RECV_LEN-recvLen) > 1) { rcv_len = recv(ftpCmdSocket->socket, (recvBuf+recvLen), MAX_RECV_LEN-recvLen-1, 0); } else { // buffer full, ignore received bytes char tmpb[16]; rcv_len = recv(ftpCmdSocket->socket, &tmpb[0], 16, 0); } if (rcv_len <= 0) { // failed ftp_log("\r\n[FTP cmd] Disconnect!\r\n"); ftpCmdSocket->clientFlag = REQ_ACTION_DISCONNECT; continue; } recvLen += rcv_len; _checkCmdResponse(); // leave only the last line in buffer timeout = mico_get_time(); recv_tmo = 0; } // ** Check DATA socket if ( (ftpDataSocket != NULL) && ((status & FTP_DATACONNECTED)) ) { if (FD_ISSET(ftpDataSocket->socket, &readset)) { // read received data to buffer int rcv_len = recv(ftpDataSocket->socket, (recvDataBuf+recvDataLen), max_recv_datalen-recvDataLen-1, 0); if (rcv_len <= 0) { // failed if (!(status & (FTP_RECEIVING | FTP_LISTING))) { ftp_log("\r\n[FTP dta] Disconnect!\r\n"); closeDataSocket(); file_status = -9; data_done = 1; } continue; } else { if ((status & FTP_RECEIVING) && (recv_type == RECV_TOFILE)) { // === write received data to file === recvDataLen = rcv_len; _saveData(0); recvDataLen = 0; } else if ((status & FTP_LISTING) || ((status & FTP_RECEIVING) && (recv_type == RECV_TOSTRING))) { if ((recvDataLen + rcv_len) < (max_recv_datalen-16)) recvDataLen += rcv_len; else recvDataLen = max_recv_datalen-16; *(recvDataBuf + recvDataLen) = '\0'; } } timeout = mico_get_time(); recv_tmo = 0; } } // ===== nothing received ================================================== recv_tmo++; if (recv_tmo < 10) continue; recv_tmo = 0; // == Check if something was received from Command socket == if (recvLen > 0) { // == Analize response === response(); recvLen = 0; memset(recvBuf, 0, MAX_RECV_LEN); } // == Check if Data socket was receiving == if ((status & (FTP_RECEIVING | FTP_LISTING))) { // Finish all operattions on data socket if ((status & FTP_RECEIVING) && (recv_type == RECV_TOFILE)) { _saveData(1); recvDataLen = 0; } else { if ((status & FTP_RECEIVING) && (recv_type == RECV_TOSTRING)) { file_status = recvDataLen; } ftp_log("[FTP dta] Data received (%d)\r\n", recvDataLen); } if ((status & FTP_LISTING)) { status &= ~FTP_LISTING; ftpCmdSocket->clientFlag = REQ_ACTION_LIST_RECEIVED; } if ((status & FTP_RECEIVING)) { status &= ~FTP_RECEIVING; ftpCmdSocket->clientFlag = REQ_ACTION_RECEIVED; } // Close data socket closeDataSocket(); data_done = 1; } } // while terminate: _ftp_deinit(0); ftp_log("\r\n[FTP trd] FTP THREAD TERMINATED\r\n"); ftp_thread_is_started = false; mico_rtos_delete_thread( NULL ); }