/*! * \brief Init the push button 3 sensor. * * \return true upon success, false if error. */ bool b_pushb3_init ( void ) { portCHAR token[6]; // Get the xCFGMutex. if( pdTRUE == x_supervisor_SemaphoreTake( xCFGMutex, 20 ) ) { // get the field if (config_file_get_value(SENSOR_PB3_CONFIG_FILE, "alarm" , token) >= 0) { // update value if (!strcmp(token, "on")) { bAlarm3 = pdTRUE; } } // Release the xCFGMutex. x_supervisor_SemaphoreGive( xCFGMutex ); } /* configure push button to produce IT on input change */ gpio_enable_pin_interrupt(PB3_POSITION , GPIO_PIN_CHANGE); /* Disable all interrupts */ Disable_global_interrupt(); /* register push button 3 handler on level 3 */ INTC_register_interrupt( (__int_handler)&vpushb_ISR, AVR32_GPIO_IRQ_0 + (PB3_POSITION/8), AVR32_INTC_INT3); /* Enable all interrupts */ Enable_global_interrupt(); return (true); }
/*! * \brief Init the temperature channel. * * \return true upon success, false if error. */ bool b_temperature_init ( void ) { portCHAR token[6]; portCHAR * unit; // Get the xCFGMutex. if( pdTRUE == x_supervisor_SemaphoreTake( xCFGMutex, 0 ) ) { // get the field if (config_file_get_value(SENSOR_TEMP_CONFIG_FILE, "alarm" , token) >= 0) { // update value if (!strcmp(token, "on")) { b_temp_alarm = pdTRUE; } } if (config_file_get_value(SENSOR_TEMP_CONFIG_FILE, "min" , token) >= 0) { unit = strpbrk(token , "C"); if (unit != NULL) { *unit = '\0'; } l_temp_min = atol(token); } if (config_file_get_value(SENSOR_TEMP_CONFIG_FILE, "max" , token) >= 0) { unit = strpbrk(token , "C"); if (unit != NULL) { *unit = '\0'; } l_temp_max = atol(token); } if (config_file_get_value(SENSOR_TEMP_CONFIG_FILE, "lograte" , token) >= 0) { ul_temp_lograte = atoi(token); } // Release the xCFGMutex. x_supervisor_SemaphoreGive( xCFGMutex ); } /* enable pin for sensor */ gpio_enable_module_pin( ADC_TEMPERATURE_PIN , ADC_TEMPERATURE_FUNCTION ); return (true); }
/*! * \brief Init the potentiometer channel. * * \return true upon success, false if error. */ bool b_potentiometer_init ( void ) { portCHAR token[6]; portCHAR * percent; // Get the xCFGMutex. if( pdTRUE == x_supervisor_SemaphoreTake( xCFGMutex, 0 ) ) { // get the field if (config_file_get_value(SENSOR_POT_CONFIG_FILE, "alarm" , token) >= 0) { // update value if (!strcmp(token, "on")) { b_pot_alarm = pdTRUE; } } if (config_file_get_value(SENSOR_POT_CONFIG_FILE, "min" , token) >= 0) { percent = strpbrk(token , "%"); if (percent != NULL) { *percent = '\0'; } sscanf(token, "%u", &ul_pot_min); } if (config_file_get_value(SENSOR_POT_CONFIG_FILE, "max" , token) >= 0) { percent = strpbrk(token , "%"); if (percent != NULL) { *percent = '\0'; } sscanf(token, "%u", &ul_pot_max); } if (config_file_get_value(SENSOR_POT_CONFIG_FILE, "lograte" , token) >= 0) { sscanf(token, "%u", &ul_pot_lograte); } // Release the xCFGMutex. x_supervisor_SemaphoreGive( xCFGMutex ); } /* enable pin for sensor */ gpio_enable_module_pin( ADC_POTENTIOMETER_PIN , ADC_POTENTIOMETER_FUNCTION ); return (true); }
/*! * \brief Init the joystick sensor. * * \return true upon success, false if error. */ bool b_joystick_init ( void ) { portCHAR token[6]; // Get the xCFGMutex. if( pdTRUE == x_supervisor_SemaphoreTake( xCFGMutex, 0 ) ) { // get the field if (config_file_get_value(SENSOR_JS_CONFIG_FILE, "alarm" , token) >= 0) { // update value if (!strcmp(token, "on")) { bAlarm = pdTRUE; } } // Release the xCFGMutex. x_supervisor_SemaphoreGive( xCFGMutex ); } /* configure joystick up to produce IT on all state change */ gpio_enable_pin_interrupt(GPIO_JOYSTICK_UP , GPIO_PIN_CHANGE); /* configure joystick down to produce IT on all state change */ gpio_enable_pin_interrupt(GPIO_JOYSTICK_DOWN , GPIO_PIN_CHANGE); /* configure joystick right to produce IT on all state change */ gpio_enable_pin_interrupt(GPIO_JOYSTICK_RIGHT , GPIO_PIN_CHANGE); /* configure joystick left to produce IT on all state change */ gpio_enable_pin_interrupt(GPIO_JOYSTICK_LEFT , GPIO_PIN_CHANGE); /* configure joystick press to produce IT on all state change */ gpio_enable_pin_interrupt(GPIO_JOYSTICK_PUSH , GPIO_PIN_CHANGE); /* Disable all interrupts */ Disable_global_interrupt(); /* register joystick handler on level 3 */ INTC_register_interrupt( (__int_handler)&vjoystick_ISR, AVR32_GPIO_IRQ_0 + (GPIO_JOYSTICK_UP/8), AVR32_INTC_INT3); INTC_register_interrupt( (__int_handler)&vjoystick_ISR, AVR32_GPIO_IRQ_0 + (GPIO_JOYSTICK_PUSH/8), AVR32_INTC_INT3); /* Enable all interrupts */ Enable_global_interrupt(); return (true); }
/*! \brief WEB server main task * check for incoming connection and process it * */ portTASK_FUNCTION( vBasicWEBServer, pvParameters ) { struct netconn *pxHTTPListener, *pxNewConnection; portCHAR token[6]; portSHORT TaskIdx; portLONG err_count; /* initialize current nb connection */ sCurrentNbHTTPConn = 0; vSemaphoreCreateBinary( xMutexNbHTTPConn ); x_default_page_len = strlen( pcDefaultPage ); /* HTTP configuration. */ // Get the xCFGMutex. if( pdFALSE == x_supervisor_SemaphoreTake( xCFGMutex, 0 ) ) { // Failed to get the CFG mutex, use the default HTTP config. webHttpPort = webHTTP_PORT; } // Mutex has been taken else { // get the field value for port number if (config_file_get_value(HTTP_CONFIG_FILE, "port" , token) >= 0) { sscanf(token, "%u", &webHttpPort); } // if it does not exist, use the default value else { webHttpPort = webHTTP_PORT; } // Release the xCFGMutex. x_supervisor_SemaphoreGive( xCFGMutex ); } // Create a new tcp connection handle pxHTTPListener = netconn_new( NETCONN_TCP ); netconn_bind(pxHTTPListener, NULL, webHttpPort ); netconn_listen( pxHTTPListener ); // Loop forever for( ;; ) { #if ( (LWIP_VERSION) == ((1U << 24) | (3U << 16) | (2U << 8) | (LWIP_VERSION_RC)) ) /* Wait for a first connection. */ pxNewConnection = netconn_accept(pxHTTPListener); #else while(netconn_accept(pxHTTPListener, &pxNewConnection) != ERR_OK) { vTaskDelay( webSHORT_DELAY ); } #endif if(pxNewConnection != NULL) { /* read the nb of connection, no need to use Mutex */ while( webHTTP_NB_CONN == sCurrentNbHTTPConn ) { vTaskDelay( webSHORT_DELAY ); } // Take the xWEBMutex if there are no active connections. if( 0 == sCurrentNbHTTPConn ) { if( pdFALSE == x_supervisor_SemaphoreTake( xWEBMutex, 0 ) ) { prvweb_SendErrorPage( pxNewConnection, 503, "", "AVR32 UC3 Web server under maintenance." ); // Close the connection. vTaskDelay( 50 ); err_count = 4; while( netconn_close( pxNewConnection ) != ERR_OK ) { if (--err_count == 0) break; vTaskDelay( webSHORT_DELAY ); } err_count = 4; while( netconn_delete( pxNewConnection ) != ERR_OK ) { if (--err_count == 0) break; vTaskDelay( webSHORT_DELAY ); } continue; } } // Find an available spot in the tTaskHandle[] array. // We're sure to find one because sCurrentNbHTTPConn < webHTTP_NB_CONN. TaskIdx = 0; while( NULL != tTaskHandle[TaskIdx] ) TaskIdx++; while( xSemaphoreTake(xMutexNbHTTPConn , portMAX_DELAY ) != pdTRUE ); sCurrentNbHTTPConn++; // Release the mutex. xSemaphoreGive( xMutexNbHTTPConn ); // TRACE_COM2( "nb http conn:%d",sCurrentNbHTTPConn ); if( xTaskCreate( prvweb_ProcessSingleConnection, ( signed portCHAR * )"WCONN", webHTTP_CONNECTION_STACK_SIZE, pxNewConnection, webHTTP_CONNECTION_PRIORITY, &tTaskHandle[TaskIdx] ) != pdPASS) { TRACE_COM2( "xTaskCreate() alloc error" ); /* delete connection */ err_count = 4; while( netconn_close( pxNewConnection ) != ERR_OK ) { if (--err_count == 0) break; vTaskDelay( webSHORT_DELAY ); } err_count = 4; while( netconn_delete( pxNewConnection ) != ERR_OK ) { if (--err_count == 0) break; vTaskDelay( webSHORT_DELAY ); } while( xSemaphoreTake(xMutexNbHTTPConn , portMAX_DELAY ) != pdTRUE ); sCurrentNbHTTPConn--; // Release the xWEBMutex if there are no active connections. if( 0 == sCurrentNbHTTPConn ) { x_supervisor_SemaphoreGive( xWEBMutex ); } // Release the mutex. xSemaphoreGive( xMutexNbHTTPConn ); }// end if task not created }// end if new connection }// end infinite loop }
/*! * \brief Task for SMTP management */ portTASK_FUNCTION( vBasicSMTPClient, pvParameters ) { struct sockaddr_in stServeurSockAddr; portLONG lRetval; portLONG lSocket = -1; portLONG ulResponseCode = 0; xMailDef * pxMail; int Size, SizeRead; portCHAR * pcRespData; int fd; portCHAR cToken[6]; // Just to stop compiler warnings. ( void ) pvParameters; // Create the xMailsQueue capable of containing DATALOG_LOGSQUEUE_SIZE ptrs // to xLogDef structures. xMailsQueue = xQueueCreate( SMTP_MAILS_QUEUE_SIZE, sizeof( xMailDef * ) ); // SMTP configuration. // Get the xCFGMutex. if( pdFALSE == x_supervisor_SemaphoreTake( xCFGMutex, 500 ) ) { // Failed to get the CFG mutex, use the default HTTP config. uiSMTPPort = SMTP_PORT; cMailTo[0] = '\0'; cMailFrom[0] = '\0'; cServerName[0] = '\0'; } // Mutex has been taken else { // get the field value for port number if (config_file_get_value(SMTP_CONFIG_FILE, "port" , cToken) >= 0) { sscanf(cToken, "%u", &uiSMTPPort); } // if it does not exist, use the default value else { uiSMTPPort = SMTP_PORT; } // try to get the mailto field if (config_file_get_value(SMTP_CONFIG_FILE, "mailto", cMailTo) < 0) { cMailTo[0] = '\0'; // can't find field in config file, warn user NAKED_TRACE_COM2("Warning : No mailto configured !!Please fill mailto= field in %s\r\n", SMTP_CONFIG_FILE); } // try to get the mailfrom field if (config_file_get_value(SMTP_CONFIG_FILE, "mailfrom", cMailFrom) < 0) { cMailFrom[0] = '\0'; // can't find field in config file, warn user NAKED_TRACE_COM2("Warning : No mailfrom configured !!Please fill mailfrom= field in %s\r\n", SMTP_CONFIG_FILE); } // try to get the server field if (config_file_get_value(SMTP_CONFIG_FILE, "server", cServerName) < 0) { cServerName[0] = '\0'; // can't find field in config file, warn user NAKED_TRACE_COM2("Warning : No server name configured !! Please fill server= field in %s\r\n", SMTP_CONFIG_FILE); } // Release the xCFGMutex. x_supervisor_SemaphoreGive( xCFGMutex ); } for(;;) { // NOTE: the task should be resumed when it is necessary to send a mail // Get the oldest mail from the queue. // NOTE: we are sure there is an item to get => no block time. if( pdTRUE == xQueueReceive( xMailsQueue, &pxMail, ( portTickType )1000 ) ) { if (cServerName[0] == '\0') { // can't find field in config file, warn user NAKED_TRACE_COM2("Warning : No server name configured !! Please fill server= field in %s\r\n", SMTP_CONFIG_FILE); } else if (cMailTo[0] == '\0') { // can't find field in config file, warn user NAKED_TRACE_COM2("Warning : No mailto configured !!Please fill mailto= field in %s\r\n", SMTP_CONFIG_FILE); } else if (cMailFrom[0] == '\0') { // can't find field in config file, warn user NAKED_TRACE_COM2("Warning : No mailfrom configured !!Please fill mailfrom= field in %s\r\n", SMTP_CONFIG_FILE); } else { // Set up port memset(&stServeurSockAddr, 0, sizeof(stServeurSockAddr)); stServeurSockAddr.sin_len = sizeof(stServeurSockAddr); stServeurSockAddr.sin_addr.s_addr = inet_addr(cServerName); stServeurSockAddr.sin_port = htons(uiSMTPPort); stServeurSockAddr.sin_family = AF_INET; // socket as a stream if ( (lSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { // socket failed NAKED_TRACE_COM2("Socket Failed\r\n"); } // connect to the server if(connect(lSocket,(struct sockaddr *)&stServeurSockAddr,sizeof(stServeurSockAddr)) < 0) { // connect failed NAKED_TRACE_COM2("Connect Failed\r\n"); } else { eSMTPCurrentState = eSMTPIdle; while ( eSMTPCurrentState != eSMTPMailSent ) { // wait for SMTP Server answer do { lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0); }while (lRetval <= 0); cTempBuffer[3] = '\0'; // Get the response code from server ulResponseCode = atoi(cTempBuffer); switch (ulResponseCode) { case 220: { // send helo send(lSocket, "HELO ", 5, 0); send(lSocket, cServerName, strlen(cServerName), 0); send(lSocket, "\r\n", 2, 0); eSMTPCurrentState = eSMTPHeloSent; break; } case 221: { // QUIT sequence has been acknowledged by server if (eSMTPCurrentState == eSMTPQuitSent) { eSMTPCurrentState = eSMTPMailSent; } break; } case 250: { if (eSMTPCurrentState == eSMTPHeloSent) { // send MAIL FROM send(lSocket, "MAIL FROM: <", 12, 0); ; send(lSocket, cMailFrom, strlen(cMailFrom), 0); send(lSocket, ">\r\n", 3, 0); eSMTPCurrentState = eSMTPMailFromSent; } else if (eSMTPCurrentState == eSMTPMailFromSent) { // send MAIL TO send(lSocket, "RCPT TO: <", 10, 0); ; send(lSocket, cMailTo, strlen(cMailTo), 0); send(lSocket, ">\r\n", 3, 0); eSMTPCurrentState = eSMTPMailToSent; } else if (eSMTPCurrentState == eSMTPMailToSent) { // send DATA send(lSocket, SMTP_DATA_STRING, 6, 0); eSMTPCurrentState = eSMTPDataSent; } else if (eSMTPCurrentState == eSMTPContentSent) { // send QUIT send(lSocket, SMTP_QUIT_STRING, 6, 0); eSMTPCurrentState = eSMTPQuitSent; } break; } case 354: { if (eSMTPCurrentState == eSMTPDataSent) { // set Subject field send(lSocket, "Subject:", 8, 0); // add subject send(lSocket, pxMail->Subject, strlen(pxMail->Subject), 0); send(lSocket, "\r\nFROM:", 7, 0); send(lSocket, cMailFrom, strlen(cMailFrom), 0); send(lSocket, "\r\nTO:", 5, 0); send(lSocket, cMailTo, strlen(cMailTo), 0); send(lSocket, "\r\n\r\n", 4, 0); // if a file has been specified, copy the content in the mail body if (pxMail->File != NULL) { // allocate response pcRespData = (portCHAR *)pvPortMalloc(SMTP_PACKET_SIZE); if (pcRespData != NULL) { if ((fd = open((const char *)pxMail->File, O_RDONLY)) >= 0) { Size = fsaccess_file_get_size(fd); // get sectors of maximum size while(Size > 0) { // get the data from filesystem SizeRead = read(fd, pcRespData, SMTP_PACKET_SIZE); // if error occurs during the read if (SizeRead <= 0) { // end the loop and send what has already been added break; } // sned data to the socket send(lSocket, pcRespData, SizeRead, 0); // decrease remaing size Size -= SizeRead; } // close the file close(fd); // free the buffer vPortFree(pcRespData); } else { // warn user : can't open the file NAKED_TRACE_COM2("Open file fails\r\n"); } } else { // warn user : can't malloc the file buffer NAKED_TRACE_COM2("SMTP : Malloc fails\r\n"); } } // add "<CRLF>.<CRLF>" send(lSocket, SMTP_MAIL_END_STRING, 5, 0); eSMTPCurrentState = eSMTPContentSent; } break; } default: { // unknown SMTP code NAKED_TRACE_COM2("Unimplented %l SMTP response from server\r\n",ulResponseCode); // break loop and reset state machine eSMTPCurrentState = eSMTPMailSent; break; } } } // close the socket close(lSocket); } // if the item was not posted from ISR if (pxMail->NeedFree == pdTRUE) { // if a file has been specified if ( pxMail->File != NULL ) { // free the item vPortFree(pxMail->File); } // free the items vPortFree(pxMail->Subject); vPortFree(pxMail); } } } } }