00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef _DJI2MAV_MAVCONTAINER_H_
00010 #define _DJI2MAV_MAVCONTAINER_H_
00011
00012
00013 #ifndef DEFAULT_RECV_LIST_SIZE
00014 #define DEFAULT_RECV_LIST_SIZE 4
00015 #endif
00016
00017 #include <mavlink/common/mavlink.h>
00018 #include <new>
00019 #include <string>
00020 #include <cstdarg>
00021 #include <algorithm>
00022
00023 #include "mavHandler.h"
00024 #include "modules/mavModule.h"
00025 #include "log.h"
00026
00027 namespace dji2mav{
00028
00029 class MavContainer{
00030 public:
00036 MavContainer(MavHandler &handler, uint16_t maxModuleNum = 8) {
00037 DJI2MAV_DEBUG("Going to construct Container with moduleNum "
00038 "%u...", maxModuleNum);
00039
00040 m_hdlr = &handler;
00041 m_maxListSize = maxModuleNum;
00042 m_currListSize = 0;
00043
00044 try {
00045 m_moduleList = new MavModule*[m_maxListSize];
00046 memset(m_moduleList, 0, m_maxListSize * sizeof(MavModule*));
00047 m_moduleMOI = new uint8_t*[m_maxListSize];
00048 memset(m_moduleMOI, 0, m_maxListSize * sizeof(uint8_t*));
00049 } catch(std::bad_alloc &m) {
00050 DJI2MAV_FATAL("Fail to allocate memory for moduleList and "
00051 "moduleMIO! Exception: %s!", m.what());
00052 exit(EXIT_FAILURE);
00053 }
00054
00055 DJI2MAV_DEBUG("...finish constructing Container.");
00056 }
00057
00058
00059 ~MavContainer() {
00060 DJI2MAV_DEBUG("Going to destruct Container...");
00061 if(NULL != m_moduleList) {
00062 for(uint16_t i = 0; i < m_maxListSize; ++i) {
00063 if(NULL != m_moduleList[i]) {
00064
00065 m_moduleList[i] = NULL;
00066 }
00067 }
00068 delete []m_moduleList;
00069 m_moduleList = NULL;
00070 }
00071 if(NULL != m_moduleMOI) {
00072 for(uint16_t i = 0; i < m_maxListSize; ++i) {
00073 if(NULL != m_moduleMOI[i]) {
00074 delete m_moduleMOI[i];
00075 m_moduleMOI[i] = NULL;
00076 }
00077 }
00078 delete []m_moduleMOI;
00079 m_moduleMOI = NULL;
00080 }
00081 DJI2MAV_DEBUG("...finish destructing Container.");
00082 }
00083
00084
00092 bool registerModule(MavModule &module, uint16_t size, ...) {
00093 if(m_currListSize == m_maxListSize) {
00094 DJI2MAV_ERROR("Fail to register module %s because "
00095 "currListSize %u reaches the limit %u!",
00096 module.getName().c_str(), m_currListSize,
00097 m_maxListSize);
00098 return false;
00099 }
00100
00101
00102
00103
00104
00105
00106 try {
00107
00108 m_moduleMOI[m_currListSize] = new uint8_t[size + 1];
00109 memset( m_moduleMOI[m_currListSize], 0,
00110 (size + 1) * sizeof(uint8_t) );
00111 } catch(std::bad_alloc &m) {
00112 DJI2MAV_FATAL( "Fail to allocate memory for moduleMOI! "
00113 "Exception: %s!", m.what() );
00114 exit(EXIT_FAILURE);
00115 }
00116
00117 m_moduleMOI[m_currListSize][0] = size;
00118
00119 va_list arg;
00120 va_start(arg, size);
00121
00122 m_moduleList[m_currListSize] = &module;
00123 for(uint16_t i = 1; i <= size; ++i) {
00124 uint8_t msgid = (uint8_t)va_arg(arg, int);
00125 m_moduleMOI[m_currListSize][i] = msgid;
00126 DJI2MAV_DEBUG( "Add msgid #%u to MOI of module %s.", msgid,
00127 module.getName().c_str() );
00128 }
00129 std::sort( m_moduleMOI[m_currListSize] + 1,
00130 m_moduleMOI[m_currListSize] + size + 1 );
00131
00132 ++m_currListSize;
00133 va_end(arg);
00134 DJI2MAV_INFO( "Succeed in registering module %s.",
00135 module.getName().c_str() );
00136 return true;
00137 }
00138
00139
00145 int getModuleIdx(std::string moduleName) {
00146 for(uint16_t i = 0; i < m_currListSize; ++i) {
00147 if( moduleName == m_moduleList[i]->getName() ) {
00148 return i;
00149 }
00150 }
00151 DJI2MAV_ERROR( "No module is named %s!", moduleName.c_str() );
00152 return -1;
00153 }
00154
00155
00162 bool hasMOI(uint16_t moduleIdx, uint8_t msgid) {
00163 if(moduleIdx >= m_currListSize) {
00164 DJI2MAV_ERROR("The index of module %u exceeds the current "
00165 "list size %u!", moduleIdx, m_currListSize);
00166 return false;
00167 }
00168
00169
00170 uint8_t *begin = m_moduleMOI[moduleIdx] + 1;
00171 uint8_t *end = m_moduleMOI[moduleIdx] +
00172 m_moduleMOI[moduleIdx][0] + 1;
00173 uint8_t *mid;
00174 while(begin <= end) {
00175 mid = begin + (end - begin) / 2;
00176 if(msgid < *mid)
00177 end = mid - 1;
00178 else if(msgid > *mid)
00179 begin = mid +1;
00180 else
00181 return true;
00182 }
00183
00184 DJI2MAV_TRACE( "Cannot find out msgid %u in module %s.", msgid,
00185 m_moduleList[moduleIdx]->getName().c_str() );
00186 return false;
00187 }
00188
00189
00196 bool hasMOI(std::string moduleName, uint8_t msgid) {
00197 int idx = getModuleIdx(moduleName);
00198 if(-1 == idx) {
00199 DJI2MAV_ERROR( "Fail to execute MOI check process because "
00200 "module name %s does not exist!",
00201 moduleName.c_str() );
00202 return false;
00203 }
00204 return hasMOI( (uint16_t)idx, msgid );
00205 }
00206
00207
00216 inline int fetchMsgFromMng(uint16_t mngIdx,
00217 mavlink_message_t* recvMsgList,
00218 mavlink_status_t* recvStatusList, uint16_t listSize) {
00219
00220 return m_hdlr->recvFromMng(mngIdx, recvMsgList, recvStatusList,
00221 listSize);
00222
00223 }
00224
00225
00233 inline int fetchMsgFromAll(mavlink_message_t* recvMsgList,
00234 mavlink_status_t* recvStatusList, uint16_t listSize) {
00235
00236 return m_hdlr->recvFromAll(recvMsgList, recvStatusList,
00237 listSize);
00238
00239 }
00240
00241
00248 bool deliverMsg(uint16_t moduleIdx,
00249 const mavlink_message_t &msg) {
00250
00251 if( hasMOI(moduleIdx, msg.msgid) ) {
00252 m_moduleList[moduleIdx]->pushMsg(moduleIdx, msg);
00253 return true;
00254 }
00255 DJI2MAV_TRACE( "Fail to deliver message to module %s!",
00256 m_moduleList[moduleIdx]->getName().c_str() );
00257 return false;
00258
00259 }
00260
00261
00268 bool deliverMsg(std::string moduleName,
00269 const mavlink_message_t &msg) {
00270
00271 int idx = getModuleIdx(moduleName);
00272 if(-1 == idx) {
00273 DJI2MAV_ERROR( "Module name %s is not matched!",
00274 moduleName.c_str() );
00275 return false;
00276 }
00277 if( hasMOI(idx, msg.msgid) ) {
00278 m_moduleList[idx]->pushMsg(idx, msg);
00279 return true;
00280 }
00281 return false;
00282
00283 }
00284
00285
00291 bool deliverMsgToAll(const mavlink_message_t &msg) {
00292 bool ret = true;
00293 for(uint8_t i = 0; i < m_currListSize; ++i) {
00294 if(NULL != m_moduleList[i] && !deliverMsg(i, msg)) {
00295 DJI2MAV_ERROR( "Fail to deliver message to module %s!",
00296 m_moduleList[i]->getName().c_str() );
00297 ret = false;
00298 }
00299 }
00300 if(!ret)
00301 DJI2MAV_ERROR("Fail to deliver message to some module!");
00302 return ret;
00303 }
00304
00305
00310 static void* thread_call(void* param) {
00311 ( (MavContainer*)param )->deliverHelper();
00312 }
00313
00314
00318 void deliverHelper() {
00319 mavlink_message_t recvMsgList[DEFAULT_RECV_LIST_SIZE];
00320 mavlink_status_t recvStatusList[DEFAULT_RECV_LIST_SIZE];
00321 while(true) {
00322 for(uint16_t i = 0; i < m_hdlr->getMaxListSize(); ++i) {
00323 int msgCnt = fetchMsgFromMng(i, recvMsgList,
00324 recvStatusList, DEFAULT_RECV_LIST_SIZE);
00325 for(uint16_t j = 0; j < msgCnt; ++j) {
00326 for(uint16_t k = 0; k < m_currListSize; ++k) {
00327 deliverMsg(k, recvMsgList[j]);
00328 }
00329 }
00330 }
00331 }
00332 }
00333
00334
00339 bool run() {
00340 int ret = pthread_create( &m_tid, NULL, thread_call,
00341 (void*)this );
00342 if(0 != ret) {
00343 DJI2MAV_FATAL("Fail to create thread for the Container!");
00344
00345 return false;
00346 }
00347
00348 for(uint16_t i = 0; i < m_currListSize; ++i) {
00349 ret &= m_moduleList[i]->run();
00350 }
00351 return ret;
00352 }
00353
00354
00355 private:
00356 MavHandler* m_hdlr;
00357
00358 MavModule** m_moduleList;
00359 uint8_t** m_moduleMOI;
00360 uint16_t m_maxListSize;
00361 uint16_t m_currListSize;
00362
00363 pthread_t m_tid;
00364
00365
00366 };
00367
00368 }
00369
00370
00371 #endif