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
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
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
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 }