static void handle_tcp_udp_client_conn_state(uint8_t link_id) { char s[32] = {0}; at.read(s, 6); if (strstr(s, "CLOSED") != NULL) { LOGI(TAG, "Server closed event."); if (aos_sem_is_valid(&g_link[link_id].sem_close)) { LOGD(TAG, "sem is going to be waked up: 0x%x", &g_link[link_id].sem_close); aos_sem_signal(&g_link[link_id].sem_close); // wakeup send task } LOGI(TAG, "Server conn (%d) closed.", link_id); } else if (strstr(s, "CONNEC") != NULL) { LOGI(TAG, "Server conn (%d) successful.", link_id); at.read(s, 3); if (aos_sem_is_valid(&g_link[link_id].sem_start)) { LOGD(TAG, "sem is going to be waked up: 0x%x", &g_link[link_id].sem_start); aos_sem_signal(&g_link[link_id].sem_start); // wakeup send task } } else if (strstr(s, "DISCON") != NULL) { LOGI(TAG, "Server conn (%d) disconnected.", link_id); at.read(s, 6); } else { LOGW(TAG, "No one handle this unkown event!!!"); } }
static int sal_wifi_close(int fd, int32_t remote_port) { int link_id; char cmd[STOP_CMD_LEN] = {0}, out[64]; link_id = fd_to_linkid(fd); if (link_id >= LINK_ID_MAX) { LOGE(TAG, "No connection found for fd (%d) in %s", fd, __func__); return -1; } snprintf(cmd, STOP_CMD_LEN - 1, "%s=%d", STOP_CMD, link_id); LOGD(TAG, "%s %d - AT cmd to run: %s", __func__, __LINE__, cmd); at.send_raw(cmd, out, sizeof(out)); LOGD(TAG, "The AT response is: %s", out); if (strstr(out, CMD_FAIL_RSP) != NULL) { LOGE(TAG, "%s %d failed", __func__, __LINE__); goto err; } if (aos_sem_wait(&g_link[link_id].sem_close, AOS_WAIT_FOREVER) != 0) { LOGE(TAG, "%s sem_wait failed", __func__); goto err; } LOGD(TAG, "%s sem_wait succeed.", __func__); err: if (aos_mutex_lock(&g_link_mutex, AOS_WAIT_FOREVER) != 0) { LOGE(TAG, "Failed to lock mutex (%s).", __func__); return -1; } if (aos_sem_is_valid(&g_link[link_id].sem_start)) { aos_sem_free(&g_link[link_id].sem_start); } if (aos_sem_is_valid(&g_link[link_id].sem_close)) { aos_sem_free(&g_link[link_id].sem_close); } g_link[link_id].fd = -1; aos_mutex_unlock(&g_link_mutex); return -1; }
static int at_worker_task_del(at_task_t *tsk) { if (NULL == tsk) { LOGE(MODULE_NAME, "invalid input %s \r\n", __func__); return -1; } aos_mutex_lock(&at.task_mutex, AOS_WAIT_FOREVER); slist_del(&tsk->next, &at.task_l); aos_mutex_unlock(&at.task_mutex); if (aos_sem_is_valid(&tsk->smpr)) { aos_sem_free(&tsk->smpr); } if (tsk) { aos_free(tsk); } return 0; }
int audio_init(void) { int ret = 0; if (aos_mutex_is_valid(&sai_mutex) || aos_sem_is_valid(&audio_sem)) { KIDS_A10_PRT("Audio module initialization had completed before now.\n"); return -1; } ret = aos_mutex_new(&sai_mutex); if (ret != 0) { KIDS_A10_PRT("aos_mutex_new return failed.\n"); return -1; } ret = aos_sem_new(&audio_sem, 0); if (ret != 0) { KIDS_A10_PRT("aos_sem_new return failed.\n"); return -1; } return 0; }
int playback_from_flash(void) { int ret = 0; int i; int pos_buff = 0; uint32_t pos_flash = 0; uint32_t part_len = DATA_BUFF_LEN / 2; uint32_t part_bytes = part_len * SAI_DATA_BYTES; uint32_t total_size = get_audio_part_len(); if (!aos_mutex_is_valid(&sai_mutex)) { KIDS_A10_PRT("aos_mutex_is_valid return false.\n"); return -1; } ret = aos_mutex_lock(&sai_mutex, SAI_WAIT_TIMEOUT); if (ret != 0) { KIDS_A10_PRT("SAI is very busy now.\n"); return -1; } if (!aos_sem_is_valid(&audio_sem)) { KIDS_A10_PRT("aos_sem_is_valid return false.\n"); ret = -1; goto PB_EXIT; } ret = reinit_sai_and_dma(SAI_dir_tx_m2p); if (ret != 0) { ret = -1; goto PB_EXIT; } printf("Playback time is %f seconds!\n", get_run_time()); #ifdef FLASH_MONO_DATA ret = hal_flash_read(PART_FOR_AUDIO, &pos_flash, &data_buff[pos_buff], part_bytes); if (ret != 0) { ret = -1; goto PB_EXIT; } ready_to_send(data_buff, part_len); ret = HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t *)data_buff, DATA_BUFF_LEN); if (ret != 0) { KIDS_A10_PRT("HAL_SAI_Transmit_DMA return failed.\n"); ret = -1; goto PB_EXIT; } while (1) { /* Wait a callback event */ while (UpdatePointer == -1) { aos_sem_wait(&audio_sem, DMA_WAIT_TIMEOUT); if (ret != 0) KIDS_A10_PRT("DMA timeout.\n"); } pos_buff = UpdatePointer; UpdatePointer = -1; /* Upate the first or the second part of the buffer */ ret = hal_flash_read(PART_FOR_AUDIO, &pos_flash, &data_buff[pos_buff], part_bytes / 2); if (ret != 0) { ret = -1; break; } ready_to_send(&data_buff[pos_buff], part_len / 2); /* check the end of the file */ if ((pos_flash + part_bytes / 2) > total_size) { ret = HAL_SAI_DMAStop(&hsai_BlockA1); if (ret != 0) { KIDS_A10_PRT("HAL_SAI_DMAStop return failed.\n"); ret = -1; } break; } if (UpdatePointer != -1) { /* Buffer update time is too long compare to the data transfer time */ KIDS_A10_PRT("UpdatePointer error.\n"); ret = -1; break; } } #else ret = hal_flash_read(PART_FOR_AUDIO, &pos_flash, &data_buff[pos_buff], DATA_BUFF_LEN * SAI_DATA_BYTES); if (ret != 0) { ret = -1; goto PB_EXIT; } ret = HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t *)data_buff, DATA_BUFF_LEN); if (ret != 0) { KIDS_A10_PRT("HAL_SAI_Transmit_DMA return failed.\n"); ret = -1; goto PB_EXIT; } while (1) { /* Wait a callback event */ while (UpdatePointer == -1) { aos_sem_wait(&audio_sem, DMA_WAIT_TIMEOUT); if (ret != 0) KIDS_A10_PRT("DMA timeout.\n"); } pos_buff = UpdatePointer; UpdatePointer = -1; /* Upate the first or the second part of the buffer */ ret = hal_flash_read(PART_FOR_AUDIO, &pos_flash, &data_buff[pos_buff], part_bytes); if (ret != 0) { ret = -1; break; } /* check the end of the file */ if ((pos_flash + part_bytes) > total_size) { ret = HAL_SAI_DMAStop(&hsai_BlockA1); if (ret != 0) { KIDS_A10_PRT("HAL_SAI_DMAStop return failed.\n"); ret = -1; } break; } if (UpdatePointer != -1) { /* Buffer update time is too long compare to the data transfer time */ KIDS_A10_PRT("UpdatePointer error.\n"); ret = -1; break; } } #endif PB_EXIT: ret = aos_mutex_unlock(&sai_mutex); if (ret != 0) { KIDS_A10_PRT("SAI release failed.\n"); } return ret; }
static int at_reset() { int ret = 0; char response[64] = {0}; char *commond = AT_RESET_CMD; if (at._mode != ASYN) { LOGE(MODULE_NAME, "Operation not supported in non asyn mode"); return -1; } at_task_t *tsk = (at_task_t *)aos_malloc(sizeof(at_task_t)); if (NULL == tsk) { LOGE(MODULE_NAME, "tsk buffer allocating failed"); return -1; } if ((ret = aos_sem_new(&tsk->smpr, 0)) != 0) { LOGE(MODULE_NAME, "failed to allocate semaphore"); goto end; } LOGD(MODULE_NAME, "at task created: %d, smpr: %d", (uint32_t)tsk, (uint32_t)&tsk->smpr); tsk->rsp = response; tsk->rsp_offset = 0; tsk->rsp_len = sizeof(response); aos_mutex_lock(&at._mutex, AOS_WAIT_FOREVER); slist_add_tail(&tsk->next, &at.task_l); // uart operation should be inside mutex lock if ((ret = hal_uart_send(&at._uart, (void *)commond, strlen(commond), at._timeout)) != 0) { aos_mutex_unlock(&at._mutex); LOGE(MODULE_NAME, "uart send command failed"); goto end; } LOGD(MODULE_NAME, "Sending command %s", commond); if ((ret = hal_uart_send(&at._uart, (void *)at._send_delimiter, strlen(at._send_delimiter), at._timeout)) != 0) { aos_mutex_unlock(&at._mutex); LOGE(MODULE_NAME, "uart send delimiter failed"); goto end; } LOGD(MODULE_NAME, "Sending delimiter %s", at._send_delimiter); aos_mutex_unlock(&at._mutex); if ((ret = aos_sem_wait(&tsk->smpr, AOS_WAIT_FOREVER)) != 0) { LOGE(MODULE_NAME, "sem_wait failed"); goto end; } LOGD(MODULE_NAME, "sem_wait succeed."); end: aos_mutex_lock(&at._mutex, AOS_WAIT_FOREVER); slist_del(&tsk->next, &at.task_l); aos_mutex_unlock(&at._mutex); if (aos_sem_is_valid(&tsk->smpr)) { aos_sem_free(&tsk->smpr); } if (tsk) { aos_free(tsk); } return ret; }
static void at_worker(void *arg) { char buf[RECV_BUFFER_SIZE] = {0}; int offset = 0; int ret = 0; int at_task_empty = 0; char c; at_task_t *tsk; LOGD(MODULE_NAME, "at_work started."); at_set_timeout(500); while (true) { // read from uart and store buf ret = at_getc(&c); if (ret != 0) { continue; } if (offset + 1 >= RECV_BUFFER_SIZE) { LOGE(MODULE_NAME, "Fatal error, no one is handling AT uart"); assert(0); } buf[offset++] = c; buf[offset] = 0; // check oob first for (int k = 0; k < at._oobs_num; k++) { oob_t *oob = &(at._oobs[k]); if (offset == oob->len && memcmp(oob->prefix, buf, oob->len) == 0) { LOGD(MODULE_NAME, "AT! %s\r\n", oob->prefix); // oob.cb is to consume uart data if necessary oob->cb(oob->arg); // start a new round after oob cb memset(buf, 0, offset); offset = 0; continue; } } at_task_empty = slist_empty(&at.task_l); // if no task, continue recv if (at_task_empty) { LOGD(MODULE_NAME, "No task in queue"); goto check_buffer; } // otherwise, get the first task in list tsk = slist_first_entry(&at.task_l, at_task_t, next); // check if a rsp end matched if (strcmp(buf + offset - strlen(RECV_STATUS_OK), RECV_STATUS_OK) == 0 || strcmp(buf + offset - strlen(RECV_STATUS_ERROR), RECV_STATUS_ERROR) == 0) { LOGD(MODULE_NAME, "AT cammand rsp matched"); LOGD(MODULE_NAME, "at task is going to be waked up: %d, smpr: %d", (uint32_t)tsk, (uint32_t)&tsk->smpr); memcpy(tsk->rsp + tsk->rsp_offset, buf, offset); tsk->rsp_offset += offset; if (aos_sem_is_valid(&tsk->smpr)) { LOGD(MODULE_NAME, "at task is going to be waked up: %d, smpr: %d", (uint32_t)tsk, (uint32_t)&tsk->smpr); aos_sem_signal(&tsk->smpr); // wakeup send task } // start a new round after a match hit goto check_buffer; } if ((offset >= (RECV_BUFFER_SIZE - 2)) || (strcmp(&buf[offset - at._recv_delim_size], at._recv_delimiter) == 0)) { if (tsk->rsp_offset + offset < tsk->rsp_len){ memcpy(tsk->rsp + tsk->rsp_offset, buf, offset); tsk->rsp_offset += offset; }else{ LOGE(MODULE_NAME, "invalid input for task reponse totlen is %d,tsk->rsp_offset is %d ,offset is %d\n", tsk->rsp_len, tsk->rsp_offset, offset); memset(tsk->rsp, 0, tsk->rsp_len); strcpy(tsk->rsp, RECV_STATUS_ERROR); if (aos_sem_is_valid(&tsk->smpr)) { LOGD(MODULE_NAME, "at task is going to be waked up: %d, smpr: %d", (uint32_t)tsk, (uint32_t)&tsk->smpr); aos_sem_signal(&tsk->smpr); // wakeup send task } } LOGD(MODULE_NAME, "Save buffer to task rsp, offset: %d tsk->rsp_offset = %d task->rsp_len is %d\n", offset, tsk->rsp_offset, tsk->rsp_len); } check_buffer: // in case buffer is full if ((offset >= (RECV_BUFFER_SIZE - 2)) || (strcmp(&buf[offset - at._recv_delim_size], at._recv_delimiter) == 0)) { LOGD(MODULE_NAME, "buffer full or new line hit, offset: %d, buf: %s", offset, buf); memset(buf, 0, offset); offset = 0; } } // never reach here return; }
/** * Example: * AT+ENETRAWSEND=<len> * ><data> * OK * * Send data in 2 stages. These 2 stages must be finished inside * one mutex lock. * 1. Send 'fst' string (first stage); * 2. Receving prompt, usually "<" character; * 3. Send data (second stage) in 'len' length. */ static int at_send_data_2stage(const char *fst, const char *data, uint32_t len, char *rsp, uint32_t rsplen/*, at_send_t t*/) { int ret = 0; if (at._mode != ASYN) { LOGE(MODULE_NAME, "Operation not supported in non asyn mode"); return -1; } if ((ret = at_reset()) != 0){ LOGE(MODULE_NAME, "There is something wrong with atparser and reset fail\n"); return -1; } at_task_t *tsk = (at_task_t *)aos_malloc(sizeof(at_task_t)); if (NULL == tsk) { LOGE(MODULE_NAME, "tsk buffer allocating failed"); return -1; } if ((ret = aos_sem_new(&tsk->smpr, 0)) != 0) { LOGE(MODULE_NAME, "failed to allocate semaphore"); goto end; } LOGD(MODULE_NAME, "at 2stage task created: %d, smpr: %d", (uint32_t)tsk, (uint32_t)&tsk->smpr); tsk->rsp = rsp; tsk->rsp_offset = 0; tsk->rsp_len = rsplen; /* The 2 stages should be inside one mutex lock*/ /* Mutex context begin*/ aos_mutex_lock(&at._mutex, AOS_WAIT_FOREVER); LOGD(MODULE_NAME, "%s: at lock got", __func__); slist_add_tail(&tsk->next, &at.task_l); // uart operation should be inside mutex lock if ((ret = hal_uart_send(&at._uart, (void *)fst, strlen(fst), at._timeout)) != 0) { aos_mutex_unlock(&at._mutex); LOGE(MODULE_NAME, "uart send 2stage prefix failed"); goto end; } LOGD(MODULE_NAME, "Sending 2stage prefix %s", fst); if ((ret = hal_uart_send(&at._uart, (void *)at._send_delimiter, strlen(at._send_delimiter), at._timeout)) != 0) { aos_mutex_unlock(&at._mutex); LOGE(MODULE_NAME, "uart send delimiter failed"); goto end; } LOGD(MODULE_NAME, "Sending delimiter %s", at._send_delimiter); if ((ret = hal_uart_send(&at._uart, (void *)data, len, at._timeout)) != 0) { aos_mutex_unlock(&at._mutex); LOGE(MODULE_NAME, "uart send 2stage data failed"); goto end; } LOGD(MODULE_NAME, "Sending 2stage data %s", data); if ((ret = hal_uart_send(&at._uart, (void *)at._send_delimiter, strlen(at._send_delimiter), at._timeout)) != 0) { aos_mutex_unlock(&at._mutex); LOGE(MODULE_NAME, "uart send delimiter failed"); goto end; } LOGD(MODULE_NAME, "Sending delimiter %s", at._send_delimiter); aos_mutex_unlock(&at._mutex); LOGD(MODULE_NAME, "%s: at lock released", __func__); /* Mutex context end*/ if ((ret = aos_sem_wait(&tsk->smpr, AOS_WAIT_FOREVER)) != 0) { LOGE(MODULE_NAME, "sem_wait failed"); goto end; } LOGD(MODULE_NAME, "sem_wait succeed."); end: aos_mutex_lock(&at._mutex, AOS_WAIT_FOREVER); slist_del(&tsk->next, &at.task_l); aos_mutex_unlock(&at._mutex); if (aos_sem_is_valid(&tsk->smpr)) aos_sem_free(&tsk->smpr); if (tsk) aos_free(tsk); return ret; }
int sal_wifi_start(sal_conn_t *c) { int link_id; char cmd[START_CMD_LEN] = {0}; char out[256] = {0}; if (!c || !c->addr) { LOGE(TAG, "%s %d - invalid argument", __func__, __LINE__); return -1; } if (aos_mutex_lock(&g_link_mutex, AOS_WAIT_FOREVER) != 0) { LOGE(TAG, "Failed to lock mutex (%s).", __func__); return -1; } for (link_id = 0; link_id < LINK_ID_MAX; link_id++) { if (g_link[link_id].fd >= 0) { continue; } else { g_link[link_id].fd = c->fd; if (aos_sem_new(&g_link[link_id].sem_start, 0) != 0) { LOGE(TAG, "failed to allocate semaphore %s", __func__); g_link[link_id].fd = -1; return -1; } if (aos_sem_new(&g_link[link_id].sem_close, 0) != 0) { LOGE(TAG, "failed to allocate semaphore %s", __func__); aos_sem_free(&g_link[link_id].sem_start); g_link[link_id].fd = -1; return -1; } break; } } aos_mutex_unlock(&g_link_mutex); // The caller should deal with this failure if (link_id >= LINK_ID_MAX) { LOGI(TAG, "No link available for now, %s failed.", __func__); return -1; } LOGD(TAG, "Creating %s connection ...", start_cmd_type_str[c->type]); switch (c->type) { case TCP_SERVER: snprintf(cmd, START_CMD_LEN - 1, "%s=%d,%s,%d,", START_CMD, link_id, start_cmd_type_str[c->type], c->l_port); break; case TCP_CLIENT: case SSL_CLIENT: snprintf(cmd, START_CMD_LEN - 5 - 1, "%s=%d,%s,%s,%d", START_CMD, link_id, start_cmd_type_str[c->type], c->addr, c->r_port); if (c->l_port >= 0) { snprintf(cmd + strlen(cmd), 7, ",%d", c->l_port); } break; case UDP_BROADCAST: case UDP_UNICAST: snprintf(cmd, START_CMD_LEN - 1, "%s=%d,%s,%s,%d,%d", START_CMD, link_id, start_cmd_type_str[c->type], c->addr, c->r_port, c->l_port); break; default: LOGE(TAG, "Invalid connection type."); goto err; } LOGD(TAG, "\r\n%s %d - AT cmd to run: %s \r\n", __func__, __LINE__, cmd); at.send_raw(cmd, out, sizeof(out)); LOGD(TAG, "The AT response is: %s", out); if (strstr(out, CMD_FAIL_RSP) != NULL) { LOGE(TAG, "%s %d failed", __func__, __LINE__); goto err; } if (aos_sem_wait(&g_link[link_id].sem_start, AOS_WAIT_FOREVER) != 0) { LOGE(TAG, "%s sem_wait failed", __func__); goto err; } LOGD(TAG, "%s sem_wait succeed.", __func__); return 0; err: if (aos_mutex_lock(&g_link_mutex, AOS_WAIT_FOREVER) != 0) { LOGE(TAG, "Failed to lock mutex (%s).", __func__); return -1; } if (aos_sem_is_valid(&g_link[link_id].sem_start)) { aos_sem_free(&g_link[link_id].sem_start); } if (aos_sem_is_valid(&g_link[link_id].sem_close)) { aos_sem_free(&g_link[link_id].sem_close); } g_link[link_id].fd = -1; aos_mutex_unlock(&g_link_mutex); return -1; }