DJI_Link.cpp
Go to the documentation of this file.
00001 
00018 #include <stdio.h>
00019 #include <string.h>
00020 #include "DJI_Link.h"
00021 #include "DJI_Codec.h"
00022 #include "DJI_API.h"
00023 
00024 #include "DJI_Logging.h"
00025 
00026 using namespace DJI::onboardSDK;
00027 
00028 CallBack callBack = 0;
00029 void* data = 0;
00030 Header *protHeader = 0;
00031 
00032 void CoreAPI::sendData(unsigned char *buf)
00033 {
00034   size_t ans;
00035   Header *pHeader = (Header *)buf;
00036 
00037 #ifdef API_TRACE_DATA
00038   printFrame(serialDevice, pHeader, true);
00039 #endif
00040 
00041   ans = serialDevice->send(buf, pHeader->length);
00042   if (ans == 0)
00043     API_LOG(serialDevice, STATUS_LOG, "Port not send");
00044   if (ans == (size_t)-1)
00045     API_LOG(serialDevice, ERROR_LOG, "Port closed");
00046 }
00047 
00048 void CoreAPI::appHandler(Header *protocolHeader)
00049 {
00050 #ifdef API_TRACE_DATA
00051     printFrame(serialDevice, protocolHeader, false);
00052 #endif
00053 
00054   Header *p2protocolHeader;
00055 
00056 
00057   if (protocolHeader->isAck == 1)
00058   {
00059     if (protocolHeader->sessionID > 1 && protocolHeader->sessionID < 32)
00060     {
00061       if (CMDSessionTab[protocolHeader->sessionID].usageFlag == 1)
00062       {
00063         serialDevice->lockMemory();
00064         p2protocolHeader = (Header *)CMDSessionTab[protocolHeader->sessionID].mmu->pmem;
00065         if (p2protocolHeader->sessionID == protocolHeader->sessionID &&
00066             p2protocolHeader->sequenceNumber == protocolHeader->sequenceNumber)
00067         {
00068           API_LOG(serialDevice, DEBUG_LOG, "Recv Session %d ACK\n", p2protocolHeader->sessionID);
00069 
00070           callBack = CMDSessionTab[protocolHeader->sessionID].handler;
00071           data = CMDSessionTab[protocolHeader->sessionID].userData;
00072           freeSession(&CMDSessionTab[protocolHeader->sessionID]);
00073           serialDevice->freeMemory();
00074           if (callBack)
00075           {
00077             if (nonBlockingCBThreadEnable == true)
00078             {
00079               notifyNonBlockingCaller(protocolHeader);
00080             }
00081             else if (nonBlockingCBThreadEnable == false)
00082             {
00083               callBack(this, protocolHeader, data);
00084             }
00085           }
00086           else
00087           {
00088            // Notify caller end of ACK frame arrived
00089            notifyCaller(protocolHeader);
00090           }
00091 
00096           setACKFrameStatus((&CMDSessionTab[protocolHeader->sessionID])->usageFlag);
00097         }
00098         else
00099         {
00100           serialDevice->freeMemory();
00101         }
00102       }  
00103     }
00104   }
00105   else
00106   {
00107     switch (protocolHeader->sessionID)
00108     {
00109       case 0:
00110         recvReqData(protocolHeader);
00111         break;
00112       case 1:
00115       default: 
00116         API_LOG(serialDevice, STATUS_LOG, "ACK %d", protocolHeader->sessionID);
00117 
00118         if (ACKSessionTab[protocolHeader->sessionID - 1].sessionStatus == ACK_SESSION_PROCESS)
00119         {
00120           API_LOG(serialDevice, DEBUG_LOG, "This session is waiting for App ACK:"
00121               "session id=%d,seq_num=%d\n",
00122               protocolHeader->sessionID, protocolHeader->sequenceNumber);
00123         }
00124         else if (ACKSessionTab[protocolHeader->sessionID - 1].sessionStatus == ACK_SESSION_IDLE)
00125         {
00126           if (protocolHeader->sessionID > 1)
00127             ACKSessionTab[protocolHeader->sessionID - 1].sessionStatus =
00128                 ACK_SESSION_PROCESS;
00129           recvReqData(protocolHeader);
00130         }
00131         else if (ACKSessionTab[protocolHeader->sessionID - 1].sessionStatus ==
00132             ACK_SESSION_USING)
00133         {
00134           serialDevice->lockMemory();
00135           p2protocolHeader = (Header *)ACKSessionTab[protocolHeader->sessionID - 1].mmu->pmem;
00136           if (p2protocolHeader->sequenceNumber == protocolHeader->sequenceNumber)
00137           {
00138             API_LOG(serialDevice, DEBUG_LOG, "Repeat ACK to remote,session "
00139                 "id=%d,seq_num=%d\n",
00140                 protocolHeader->sessionID, protocolHeader->sequenceNumber);
00141             sendData(ACKSessionTab[protocolHeader->sessionID - 1].mmu->pmem);
00142             serialDevice->freeMemory();
00143           }
00144           else
00145           {
00146             API_LOG(serialDevice, DEBUG_LOG,
00147                 "Same session,but new seq_num pkg,session id=%d,"
00148                 "pre seq_num=%d,cur seq_num=%d\n",
00149                 protocolHeader->sessionID, p2protocolHeader->sequenceNumber,
00150                 protocolHeader->sequenceNumber);
00151             ACKSessionTab[protocolHeader->sessionID - 1].sessionStatus =
00152               ACK_SESSION_PROCESS;
00153             serialDevice->freeMemory();
00154             recvReqData(protocolHeader);
00155           }
00156         }
00157         break;
00158     }
00159   }
00160 }
00161 
00162 void CoreAPI::allocateACK(Header *protocolHeader) {
00163 
00164   const size_t MAX_ACK_SIZE = (versionData.version == versionM100_31) ?
00165     M100_MAX_ACK_SIZE : A3_MAX_ACK_SIZE;
00166 
00167   if (protocolHeader->length <= MAX_ACK_SIZE)
00168   {
00169     memcpy(missionACKUnion.raw_ack_array, ((unsigned char *)protocolHeader) + sizeof(Header),
00170         (protocolHeader->length - EXC_DATA_SIZE));
00171   }
00172   else
00173   {
00174     throw std::runtime_error("Unknown ACK");
00175   }
00176 }
00177 
00178 void CoreAPI::notifyCaller(Header *protocolHeader)
00179 {
00180   serialDevice->lockACK();
00181 
00182   allocateACK(protocolHeader);
00183 
00184   // Notify caller end of ACK frame arrived
00185   serialDevice->notify();
00186   serialDevice->freeACK();
00187 }
00188 
00189 void CoreAPI::notifyNonBlockingCaller(Header *protocolHeader)
00190 {
00191 
00192     serialDevice->lockNonBlockCBAck();
00195 
00196     allocateACK(protocolHeader);
00197 
00201     protHeader = protocolHeader;
00202     serialDevice->freeNonBlockCBAck();
00203 
00204     serialDevice->lockProtocolHeader();
00205     serialDevice->notifyNonBlockCBAckRecv();
00206     serialDevice->freeProtocolHeader();
00207 }
00208 
00209 void CoreAPI::sendPoll()
00210 {
00211   unsigned char i;
00212   time_ms curTimestamp;
00213   for (i = 1; i < SESSION_TABLE_NUM; i++)
00214   {
00215     if (CMDSessionTab[i].usageFlag == 1)
00216     {
00217       curTimestamp = serialDevice->getTimeStamp();
00218       if ((curTimestamp - CMDSessionTab[i].preTimestamp) > CMDSessionTab[i].timeout)
00219       {
00220         serialDevice->lockMemory();
00221         if (CMDSessionTab[i].retry > 0)
00222         {
00223           if (CMDSessionTab[i].sent >= CMDSessionTab[i].retry)
00224           {
00225             API_LOG(serialDevice, DEBUG_LOG, "Free session %d\n",
00226                 CMDSessionTab[i].sessionID);
00227 
00228             freeSession(&CMDSessionTab[i]);
00229           }
00230           else
00231           {
00232             API_LOG(serialDevice, DEBUG_LOG, "Retry session %d\n",
00233                 CMDSessionTab[i].sessionID);
00234             sendData(CMDSessionTab[i].mmu->pmem);
00235             CMDSessionTab[i].preTimestamp = curTimestamp;
00236             CMDSessionTab[i].sent++;
00237           }
00238         }
00239         else
00240         {
00241           API_LOG(serialDevice, DEBUG_LOG, "Send once %d\n", i);
00242           sendData(CMDSessionTab[i].mmu->pmem);
00243           CMDSessionTab[i].preTimestamp = curTimestamp;
00244         }
00245         serialDevice->freeMemory();
00246       }
00247       else
00248       {
00249         API_LOG(serialDevice, DEBUG_LOG, "Timeout Session: %d \n", i);
00250       }
00251     }
00252   }
00254 }
00255 
00256 void CoreAPI::readPoll()
00257 {
00258   int read_len;
00259   uint8_t buf[BUFFER_SIZE];
00260   read_len = serialDevice->readall(buf, BUFFER_SIZE);
00261 #ifdef API_BUFFER_DATA
00262   onceRead = read_len;
00263   totalRead += onceRead;
00264 #endif // API_BUFFER_DATA
00265   for (int i = 0; i < read_len; i++)
00266   {
00267     byteHandler(buf[i]);
00268   }
00269 }
00270 
00272 void CoreAPI::callbackPoll(CoreAPI *api)
00273 {
00274   serialDevice->lockNonBlockCBAck();
00275   serialDevice->nonBlockWait();
00278   callBack(api,protHeader,data);
00279   serialDevice->freeNonBlockCBAck();
00280 }
00281 
00282 void CoreAPI::setup()
00283 {
00284   setupMMU();
00285   setupSession();
00286 }
00287 
00288 void CoreAPI::setKey(const char *key)
00289 {
00290   transformTwoByte(key, filter.sdkKey);
00291   filter.encode = 1;
00292 }
00293 
00294 void CoreAPI::setActivation(bool isActivated)
00295 {
00296   if (isActivated)
00297     broadcastData.activation = 1;
00298   else
00299     broadcastData.activation = 0;
00300 }
00301 
00302 void DJI::onboardSDK::CoreAPI::setACKFrameStatus(uint32_t usageFlag)
00303 {
00304   ackFrameStatus = usageFlag;
00305 }
00306 
00307 uint32_t DJI::onboardSDK::CoreAPI::getACKFrameStatus()
00308 {
00309   return ackFrameStatus;
00310 }
00311 
00312 void CoreAPI::setSyncFreq(uint32_t freqInHz)
00313 {
00314   send(0, 1, SET_SYNC, CODE_SYNC_BROADCAST, &freqInHz, sizeof(freqInHz));
00315 }
00316 
00317 unsigned short calculateLength(unsigned short size, unsigned short encrypt_flag)
00318 {
00319   unsigned short len;
00320   if (encrypt_flag)
00321     len = size + sizeof(Header) + 4 + (16 - size % 16);
00322   else
00323     len = size + sizeof(Header) + 4;
00324   return len;
00325 }
00326 
00327 int CoreAPI::ackInterface(Ack *parameter)
00328 {
00329   unsigned short ret = 0;
00330   ACKSession *ack_session = (ACKSession *)NULL;
00331 
00332   if (parameter->length > PRO_PURE_DATA_MAX_SIZE)
00333   {
00334     API_LOG(serialDevice, ERROR_LOG, "length=%d is over-sized\n", parameter->length);
00335     return -1;
00336   }
00337 
00338   if (parameter->sessionID == 0)
00339   {
00341     return 0;
00342   }
00343   else if (parameter->sessionID > 0 && parameter->sessionID < 32)
00344   {
00345     serialDevice->lockMemory();
00346     ack_session = allocACK(parameter->sessionID,
00347         calculateLength(parameter->length, parameter->encrypt));
00348     if (ack_session == (ACKSession *)NULL)
00349     {
00350       serialDevice->freeMemory();
00351       return -1;
00352     }
00353 
00354     ret = encrypt(ack_session->mmu->pmem, parameter->buf, parameter->length, 1,
00355         parameter->encrypt, parameter->sessionID, parameter->seqNum);
00356     if (ret == 0)
00357     {
00358       API_LOG(serialDevice, ERROR_LOG, "encrypt ERROR\n");
00359       serialDevice->freeMemory();
00360       return -1;
00361     }
00362 
00363     API_LOG(serialDevice, DEBUG_LOG, "Sending data!");
00364     sendData(ack_session->mmu->pmem);
00365     serialDevice->freeMemory();
00366     ack_session->sessionStatus = ACK_SESSION_USING;
00367     return 0;
00368   }
00369 
00370   return -1;
00371 }
00372 
00373 int CoreAPI::sendInterface(Command *parameter)
00374 {
00375   unsigned short ret = 0;
00376   CMDSession *cmdSession = (CMDSession *)NULL;
00377   if (parameter->length > PRO_PURE_DATA_MAX_SIZE)
00378   {
00379     API_LOG(serialDevice, ERROR_LOG, "ERROR,length=%lu is over-sized\n", parameter->length);
00380     return -1;
00381   }
00382 
00383   switch (parameter->sessionMode)
00384   {
00385     case 0:
00386       serialDevice->lockMemory();
00387       cmdSession = allocSession(CMD_SESSION_0,
00388           calculateLength(parameter->length, parameter->encrypt));
00389 
00390       if (cmdSession == (CMDSession *)NULL)
00391       {
00392         serialDevice->freeMemory();
00393         API_LOG(serialDevice, ERROR_LOG, "ERROR,there is not enough memory\n");
00394         return -1;
00395       }
00396       ret = encrypt(cmdSession->mmu->pmem, parameter->buf, parameter->length, 0,
00397           parameter->encrypt, cmdSession->sessionID, seq_num);
00398       if (ret == 0)
00399       {
00400         API_LOG(serialDevice, ERROR_LOG, "encrypt ERROR\n");
00401         freeSession(cmdSession);
00402         serialDevice->freeMemory();
00403         return -1;
00404       }
00405 
00406       API_LOG(serialDevice, DEBUG_LOG, "send data in session mode 0\n");
00407 
00408       sendData(cmdSession->mmu->pmem);
00409       seq_num++;
00410       freeSession(cmdSession);
00411       serialDevice->freeMemory();
00412       break;
00413     case 1:
00414       serialDevice->lockMemory();
00415       cmdSession = allocSession(CMD_SESSION_1,
00416           calculateLength(parameter->length, parameter->encrypt));
00417       if (cmdSession == (CMDSession *)NULL)
00418       {
00419         serialDevice->freeMemory();
00420         API_LOG(serialDevice, ERROR_LOG, "ERROR,there is not enough memory\n");
00421         return -1;
00422       }
00423       if (seq_num == cmdSession->preSeqNum)
00424       {
00425         seq_num++;
00426       }
00427       ret = encrypt(cmdSession->mmu->pmem, parameter->buf, parameter->length, 0,
00428           parameter->encrypt, cmdSession->sessionID, seq_num);
00429       if (ret == 0)
00430       {
00431         API_LOG(serialDevice, ERROR_LOG, "encrypt ERROR\n");
00432         freeSession(cmdSession);
00433         serialDevice->freeMemory();
00434         return -1;
00435       }
00436       cmdSession->preSeqNum = seq_num++;
00437 
00438       cmdSession->handler = parameter->handler;
00439       cmdSession->userData = parameter->userData;
00440       cmdSession->timeout =
00441           (parameter->timeout > POLL_TICK) ? parameter->timeout : POLL_TICK;
00442       cmdSession->preTimestamp = serialDevice->getTimeStamp();
00443       cmdSession->sent = 1;
00444       cmdSession->retry = 1;
00445       API_LOG(serialDevice, DEBUG_LOG, "sending session %d\n", cmdSession->sessionID);
00446       sendData(cmdSession->mmu->pmem);
00447       serialDevice->freeMemory();
00448       break;
00449 
00450     // Case 2 is almost the same as case 1, except CMD_SESSION_AUTO and retry settings.
00451     case 2:
00452       serialDevice->lockMemory();
00453       cmdSession = allocSession(CMD_SESSION_AUTO,
00454           calculateLength(parameter->length, parameter->encrypt));
00455       if (cmdSession == (CMDSession *)NULL)
00456       {
00457         serialDevice->freeMemory();
00458         API_LOG(serialDevice, ERROR_LOG, "ERROR,there is not enough memory\n");
00459         return -1;
00460       }
00461       if (seq_num == cmdSession->preSeqNum)
00462       {
00463         seq_num++;
00464       }
00465       ret = encrypt(cmdSession->mmu->pmem, parameter->buf, parameter->length, 0,
00466           parameter->encrypt, cmdSession->sessionID, seq_num);
00467 
00468       if (ret == 0)
00469       {
00470         API_LOG(serialDevice, ERROR_LOG, "encrypt ERROR");
00471         freeSession(cmdSession);
00472         serialDevice->freeMemory();
00473         return -1;
00474       }
00475       cmdSession->preSeqNum = seq_num++;
00476       cmdSession->handler = parameter->handler;
00477       cmdSession->userData = parameter->userData;
00478       cmdSession->timeout =
00479           (parameter->timeout > POLL_TICK) ? parameter->timeout : POLL_TICK;
00480       cmdSession->preTimestamp = serialDevice->getTimeStamp();
00481       cmdSession->sent = 1;
00482       cmdSession->retry = parameter->retry;
00483       API_LOG(serialDevice, DEBUG_LOG, "Sending session %d\n", cmdSession->sessionID);
00484       sendData(cmdSession->mmu->pmem);
00485       serialDevice->freeMemory();
00486       break;
00487     default:
00488       API_LOG(serialDevice, ERROR_LOG, "Unknown mode:%d\n", parameter->sessionMode);
00489       break;
00490   }
00491   return 0;
00492 }


dji_sdk_lib
Author(s):
autogenerated on Thu Jun 6 2019 17:55:25