Send file data through D7A Action Protocol demo.
Dependencies: modem_ref_helper
main.cpp
00001 // @autor: jeremie@wizzilab.com 00002 // @date: 2017-05-02 00003 00004 #include "modem_ref_helper.h" 00005 #include "modem_callbacks.h" 00006 #include "files.h" 00007 #include "sensor.h" 00008 00009 #define MIN_REPORT_PERIOD (10) // Seconds 00010 00011 Semaphore modem_ready(0); 00012 sensor_config_t g_light_config; 00013 Queue<void, 8> g_file_modified; 00014 00015 // Callback for id User 00016 void my_main_callback(uint8_t terminal, int8_t err, uint8_t id) 00017 { 00018 UNUSED(id); 00019 00020 if (ALP_ERR_NONE > err) 00021 { 00022 modem_print_error(ALP_ITF_TYPE_D7A, err); 00023 } 00024 00025 if (terminal) 00026 { 00027 modem_ready.release(); 00028 } 00029 } 00030 00031 static bool report_ok(uint32_t last_report_time) 00032 { 00033 // Do not send a report if it's been less than MIN_REPORT_PERIOD since the last report 00034 if ((last_report_time/1000) < MIN_REPORT_PERIOD) 00035 { 00036 PRINT("Report Skipped, next in %ds min\n", MIN_REPORT_PERIOD - (last_report_time/1000)); 00037 return false; 00038 } 00039 00040 return true; 00041 } 00042 00043 // Check parameters to see if data should be send 00044 static bool report_needed(sensor_config_t* config, int32_t value, int32_t last_value, uint32_t last_report_time, uint8_t id) 00045 { 00046 switch (config->report_type) 00047 { 00048 case REPORT_ALWAYS: 00049 // Send a report at each measure 00050 PRINT("Report[%d] always\r\n", id); 00051 return report_ok(last_report_time); 00052 case REPORT_ON_DIFFERENCE: 00053 // Send a report when the difference between the last reported measure and the current mesure is greater than max_diff 00054 if (abs(last_value - value) >= config->max_diff && config->max_diff) 00055 { 00056 PRINT("Report[%d] on difference (last:%d new:%d max_diff:%d)\r\n", id, last_value, value, config->max_diff); 00057 return report_ok(last_report_time); 00058 } 00059 break; 00060 case REPORT_ON_THRESHOLD: 00061 // Send a report when crossing a threshold 00062 if ( (value >= config->threshold_high && last_value < config->threshold_high) 00063 || (value <= config->threshold_low && last_value > config->threshold_low) 00064 || (value < config->threshold_high && last_value >= config->threshold_high) 00065 || (value > config->threshold_low && last_value <= config->threshold_low)) 00066 { 00067 PRINT("Report[%d] on threshold (last:%d new:%d th:%d tl:%d)\r\n", id, last_value, value, config->threshold_high, config->threshold_low); 00068 return report_ok(last_report_time); 00069 } 00070 break; 00071 default: 00072 break; 00073 } 00074 00075 // Send a report if it's been more than max_period since the last report 00076 if (((last_report_time/1000) >= config->max_period) && config->max_period) 00077 { 00078 PRINT("Report[%d] on period (max_period:%d time:%d)\r\n", id, config->max_period, last_report_time); 00079 return report_ok(last_report_time); 00080 } 00081 00082 return false; 00083 } 00084 00085 void thread_sensor_light() 00086 { 00087 light_value_t light_level; 00088 light_value_t light_level_old = 0; 00089 00090 // To force a first report 00091 uint32_t last_report_time = 0xFFFFFFFF; 00092 uint8_t id = modem_get_id(my_main_callback); 00093 00094 FPRINT("(id:0x%08x)\r\n", osThreadGetId()); 00095 00096 // Get the sensor configuration 00097 ram_fs_read(FID_SENSOR_CONFIG, 0, SIZE_SENSOR_CONFIG, (uint8_t*)&g_light_config); 00098 00099 while (true) 00100 { 00101 light_level = sensor_get_light(); 00102 00103 PRINT("Light %d\r\n", light_level); 00104 00105 if (report_needed(&g_light_config, light_level, light_level_old, last_report_time, id)) 00106 { 00107 PRINT("Light report %d\r\n", light_level); 00108 00109 // Send notification 00110 modem_write_file(FID_SENSOR_LIGHT, &light_level, 0, SIZE_SENSOR_LIGHT, id); 00111 modem_ready.acquire(); 00112 00113 // Update 00114 light_level_old = light_level; 00115 last_report_time = 0; 00116 } 00117 00118 // Update last report time 00119 last_report_time += g_light_config.read_period; 00120 00121 ThisThread::sleep_for(g_light_config.read_period); 00122 } 00123 } 00124 00125 void thread_file_modified() 00126 { 00127 uint8_t fid; 00128 osEvent evt; 00129 00130 while (true) 00131 { 00132 evt = g_file_modified.get(); 00133 fid = (evt.status == osEventMessage)? (uint8_t)(uint32_t)evt.value.p : NULL; 00134 00135 switch (fid) 00136 { 00137 case FID_SENSOR_CONFIG: 00138 // Update sensor configuration 00139 ram_fs_read(FID_SENSOR_CONFIG, 0, SIZE_SENSOR_CONFIG, (uint8_t*)&g_light_config); 00140 PRINT("Sensor configuration updated\r\n"); 00141 break; 00142 default: 00143 break; 00144 } 00145 } 00146 } 00147 00148 // Misc 00149 // ============================================================{{{ 00150 00151 void my_get_alp_file_props(uint8_t fid, alp_file_header_t* hdr) 00152 { 00153 memcpy(hdr, ram_fs_get_header(fid), sizeof(alp_file_header_t)); 00154 } 00155 00156 modem_callbacks_t callbacks = { 00157 .read = my_read, 00158 .write = my_write, 00159 .read_fprop = my_read_fprop, 00160 .flush = my_flush, 00161 .remove = my_delete, 00162 .udata = my_udata, 00163 .lqual = my_lqual, 00164 .ldown = my_ldown, 00165 .reset = my_reset, 00166 .boot = my_boot, 00167 .busy = my_busy, 00168 }; 00169 00170 /*** Main function ------------------------------------------------------------- ***/ 00171 int main() 00172 { 00173 // Start & initialize 00174 #ifdef DEBUG_LED 00175 DBG_OPEN(DEBUG_LED); 00176 #else 00177 DBG_OPEN(NC); 00178 #endif 00179 PRINT("\n" 00180 "-----------------------------------------\n" 00181 "---------- Demo send and forget ---------\n" 00182 "-----------------------------------------\n"); 00183 00184 modem_helper_open(&callbacks); 00185 00186 uint8_t id = modem_get_id(my_main_callback); 00187 00188 DPRINT("Register Files\n"); 00189 00190 // Create report file on modem. 00191 modem_update_file(FID_SENSOR_LIGHT, (alp_file_header_t*)&h_sensor_light, NULL); 00192 00193 // Allow remote access. 00194 modem_update_file(FID_SENSOR_CONFIG, (alp_file_header_t*)&h_sensor_config, (uint8_t*)&f_sensor_config); 00195 00196 // Configure URC: LQUAL on report file notification every 10 reports 00197 PRINT("Setup URCs\n"); 00198 modem_enable_urc(ALP_URC_TYPE_LQUAL, IFID_REPORT, 10, true, id); 00199 modem_ready.acquire(); 00200 00201 PRINT("Start D7A Stack\n"); 00202 modem_activate_itf(ALP_ITF_TYPE_D7A, 24, 0, ALP_D7A_ISTAT_RESP | ALP_D7A_ISTAT_UNS | ALP_D7A_ISTAT_EOP, true, id); 00203 modem_ready.acquire(); 00204 00205 PRINT("Notify Modem Version\n"); 00206 modem_notify_file(D7A_FID_FIRMWARE_VERSION, 0, SIZE_HOST_REV, id); 00207 modem_ready.acquire(); 00208 00209 PRINT("Notify FW Version\n"); 00210 uint8_t default_root_key[16] = DEFAULT_ROOT_KEY; 00211 modem_notify_host_rev(&f_rev, &h_rev, default_root_key); 00212 00213 modem_free_id(id); 00214 00215 // Start file modified thread 00216 Thread th_file_modified(osPriorityNormal, 1024, NULL); 00217 osStatus status = th_file_modified.start(thread_file_modified); 00218 ASSERT(status == osOK, "Failed to start thread_file_modified (err: %d)\r\n", status); 00219 00220 // Start light measure thread 00221 Thread th_sensor_light(osPriorityNormal, 1024, NULL); 00222 status = th_sensor_light.start(thread_sensor_light); 00223 ASSERT(status == osOK, "Failed to start thread_sensor_light (err: %d)\r\n", status); 00224 00225 #ifdef DEBUG_LED 00226 DigitalOut my_led(DEBUG_LED); 00227 #endif 00228 00229 // Set main task to lowest priority 00230 osThreadSetPriority(osThreadGetId(), osPriorityLow); 00231 while(true) 00232 { 00233 ThisThread::sleep_for(500); 00234 #ifdef DEBUG_LED 00235 my_led = !my_led; 00236 #endif 00237 } 00238 }
Generated on Wed Jul 13 2022 06:50:39 by 1.7.2