1 /******************************************************************************
3 @file OADProtocol.c
5 @brief Sub1G Over the Air Download Protocol Module
7 Group: WCS LPC
8 $Target Devices: Linux: AM335x, Embedded Devices: CC1310, CC1350, CC1352$
10 ******************************************************************************
11 $License: BSD3 2016 $
13 Copyright (c) 2015, Texas Instruments Incorporated
14 All rights reserved.
16 Redistribution and use in source and binary forms, with or without
17 modification, are permitted provided that the following conditions
18 are met:
20 * Redistributions of source code must retain the above copyright
21 notice, this list of conditions and the following disclaimer.
23 * Redistributions in binary form must reproduce the above copyright
24 notice, this list of conditions and the following disclaimer in the
25 documentation and/or other materials provided with the distribution.
27 * Neither the name of Texas Instruments Incorporated nor the names of
28 its contributors may be used to endorse or promote products derived
29 from this software without specific prior written permission.
31 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
33 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
34 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
35 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
36 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
37 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
38 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
39 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
40 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
41 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 ******************************************************************************
43 $Release Name: TI-15.4Stack Linux x64 SDK$
44 $Release Date: Sept 27, 2017 (2.04.00.13)$
45 *****************************************************************************/
47 /***** Includes *****/
49 #include <string.h>
51 #include <common/native_oad/oad_protocol.h>
53 /***** Defines *****/
55 typedef OADProtocol_Status_t (*incomingPacketProcessFn_t)(void* pSrcAddress, uint8_t *pIncomingPacket);
57 typedef struct {
58 uint8_t cmdId;
59 incomingPacketProcessFn_t packetprocessFn;
60 }incomingPacketProcess_t;
62 static OADProtocol_Status_t processFwVersioReq(void* pSrcAddress, uint8_t *pIncomingPacket);
63 static OADProtocol_Status_t processFwVersioRsp(void* pSrcAddress, uint8_t *pIncomingPacket);
64 static OADProtocol_Status_t processOadImgIdentifyReq(void* pSrcAddress, uint8_t *pIncomingPacket);
65 static OADProtocol_Status_t processOadImgIdentifyRsp(void* pSrcAddress, uint8_t *pIncomingPacket);
66 static OADProtocol_Status_t processOadImgBlockReq(void* pSrcAddr, uint8_t *pIncomingPacket);
67 static OADProtocol_Status_t processOadImgBlockRsp(void* pSrcAddress, uint8_t *pIncomingPacket);
69 static incomingPacketProcess_t incomingPacketProcessTable[] =
70 {
71 {OADProtocol_PACKET_TYPE_FW_VERSION_REQ, processFwVersioReq},
72 {OADProtocol_PACKET_TYPE_FW_VERSION_RSP, processFwVersioRsp},
73 {OADProtocol_PACKET_TYPE_OAD_IMG_IDENTIFY_REQ, processOadImgIdentifyReq},
74 {OADProtocol_PACKET_TYPE_OAD_IMG_IDENTIFY_RSP, processOadImgIdentifyRsp},
75 {OADProtocol_PACKET_TYPE_OAD_BLOCK_REQ, processOadImgBlockReq},
76 {OADProtocol_PACKET_TYPE_OAD_BLOCK_RSP, processOadImgBlockRsp},
77 };
79 /***** Variable declarations *****/
81 /* Set Default parameters structure */
82 static const OADProtocol_Params_t OADProtocol_defaultParams = {
83 .pRadioAccessFxns = 0,
84 .pProtocolMsgCallbacks = 0,
85 };
87 static OADProtocol_Params_t OADProtocol_params;
89 /***** Function definitions *****/
90 void OADProtocol_init(void) {
92 }
94 void OADProtocol_Params_init(OADProtocol_Params_t *params)
95 {
96 *params = OADProtocol_defaultParams;
97 }
99 void OADProtocol_open(OADProtocol_Params_t *params)
100 {
101 // Populate default params if not provided
102 if (params == NULL)
103 {
104 OADProtocol_Params_init(&OADProtocol_params);
105 params = &OADProtocol_params;
106 memcpy(params, &OADProtocol_params, sizeof(OADProtocol_Params_t));
107 }
108 else
109 {
110 memcpy(&OADProtocol_params, params, sizeof(OADProtocol_Params_t));
111 }
112 }
114 OADProtocol_Status_t OADProtocol_ParseIncoming(void* pSrcAddress, uint8_t* incomingPacket)
115 {
116 uint8_t cbIdx;
117 OADProtocol_Status_t status = OADProtocol_Failed;
119 /* Process the message */
120 for(cbIdx = 0; cbIdx < (sizeof(incomingPacketProcessTable) / sizeof(incomingPacketProcess_t)) ;cbIdx++)
121 {
122 if(incomingPacketProcessTable[cbIdx].cmdId == incomingPacket[OADProtocol_PKT_CMDID_OFFSET])
123 {
124 status = incomingPacketProcessTable[cbIdx].packetprocessFn(pSrcAddress, incomingPacket);
125 }
126 }
128 return status;
129 }
131 OADProtocol_Status_t OADProtocol_sendFwVersionReq(void* pDstAddress)
132 {
133 OADProtocol_Status_t status = OADProtocol_Failed;
134 uint8_t* pFwVersionReqPacket;
136 //Allocate the buffer
137 if(OADProtocol_params.pRadioAccessFxns->pfnRadioAccessAllocMsg)
138 {
139 pFwVersionReqPacket = OADProtocol_params.pRadioAccessFxns->pfnRadioAccessAllocMsg(
140 OADProtocol_PACKET_TYPE_FW_VERSION_REQ_LEN);
141 }
143 pFwVersionReqPacket[OADProtocol_PKT_CMDID_OFFSET] = OADProtocol_PACKET_TYPE_FW_VERSION_REQ;
145 if(OADProtocol_params.pRadioAccessFxns->pfnRadioAccessPacketSend)
146 {
147 status = OADProtocol_params.pRadioAccessFxns->pfnRadioAccessPacketSend(pDstAddress,
148 pFwVersionReqPacket,
149 OADProtocol_PACKET_TYPE_FW_VERSION_REQ_LEN);
150 }
152 return status;
153 }
155 OADProtocol_Status_t OADProtocol_sendFwVersionRsp(void* pDstAddress, char *fwVersion)
156 {
157 OADProtocol_Status_t status = OADProtocol_Failed;
158 uint8_t* pFwVersionRspPacket;
160 //Allocate the buffer
161 if(OADProtocol_params.pRadioAccessFxns->pfnRadioAccessAllocMsg)
162 {
163 pFwVersionRspPacket =OADProtocol_params.pRadioAccessFxns->pfnRadioAccessAllocMsg(
164 OADProtocol_PACKET_TYPE_FW_VERSION_RSP_LEN);
165 }
167 pFwVersionRspPacket[OADProtocol_PKT_CMDID_OFFSET] = OADProtocol_PACKET_TYPE_FW_VERSION_RSP;
168 memcpy(&(pFwVersionRspPacket[OADProtocol_VER_RSP_VERSIONSTRING_OFFSET]), fwVersion, OADProtocol_FW_VERSION_STR_LEN);
170 if(OADProtocol_params.pRadioAccessFxns->pfnRadioAccessPacketSend)
171 {
172 status = OADProtocol_params.pRadioAccessFxns->pfnRadioAccessPacketSend(pDstAddress,
173 pFwVersionRspPacket,
174 OADProtocol_PACKET_TYPE_FW_VERSION_RSP_LEN);
175 }
177 return status;
178 }
180 OADProtocol_Status_t OADProtocol_sendImgIdentifyReq(void* pDstAddress, uint8_t imgId, uint8_t *pImgInfoData)
181 {
182 OADProtocol_Status_t status = OADProtocol_Failed;
183 uint8_t* pOadImgIdentifyReqPacket;
185 //Allocate the buffer
186 if(OADProtocol_params.pRadioAccessFxns->pfnRadioAccessAllocMsg)
187 {
188 pOadImgIdentifyReqPacket = OADProtocol_params.pRadioAccessFxns->pfnRadioAccessAllocMsg(
189 OADProtocol_PACKET_TYPE_OAD_IMG_IDENTIFY_REQ_LEN);
190 }
192 pOadImgIdentifyReqPacket[OADProtocol_PKT_CMDID_OFFSET] = OADProtocol_PACKET_TYPE_OAD_IMG_IDENTIFY_REQ;
193 pOadImgIdentifyReqPacket[OADProtocol_IMG_IDENTIFY_REQ_IMG_ID_OFFSET] = imgId;
194 memcpy(&(pOadImgIdentifyReqPacket[OADProtocol_IMG_IDENTIFY_REQ_IMG_HDR_OFFSET]), pImgInfoData, 16);
196 if(OADProtocol_params.pRadioAccessFxns->pfnRadioAccessPacketSend)
197 {
198 status = OADProtocol_params.pRadioAccessFxns->pfnRadioAccessPacketSend(pDstAddress,
199 pOadImgIdentifyReqPacket,
200 OADProtocol_PACKET_TYPE_OAD_IMG_IDENTIFY_REQ_LEN);
201 }
203 return status;
204 }
206 OADProtocol_Status_t OADProtocol_sendOadIdentifyImgRsp(void* pDstAddress, uint8_t rspStatus)
207 {
208 uint8_t* pOadImgIdentifyRspPacket;
209 OADProtocol_Status_t status = OADProtocol_Failed;
211 //Allocate the buffer
212 if(OADProtocol_params.pRadioAccessFxns->pfnRadioAccessAllocMsg)
213 {
214 pOadImgIdentifyRspPacket = OADProtocol_params.pRadioAccessFxns->pfnRadioAccessAllocMsg(
215 sizeof (OADProtocol_PACKET_TYPE_OAD_IMG_IDENTIFY_RSP_LEN));
216 }
218 pOadImgIdentifyRspPacket[OADProtocol_PKT_CMDID_OFFSET] = OADProtocol_PACKET_TYPE_OAD_IMG_IDENTIFY_RSP;
219 pOadImgIdentifyRspPacket[OADProtocol_IMG_IDENTIFY_RSP_STATUS_OFFSET] = rspStatus;
221 if(OADProtocol_params.pRadioAccessFxns->pfnRadioAccessPacketSend)
222 {
223 status = OADProtocol_params.pRadioAccessFxns->pfnRadioAccessPacketSend(pDstAddress,
224 pOadImgIdentifyRspPacket,
225 OADProtocol_PACKET_TYPE_OAD_IMG_IDENTIFY_RSP_LEN);
226 }
228 return status;
229 }
231 OADProtocol_Status_t OADProtocol_sendOadImgBlockReq(void* pDstAddress, uint8_t imgId, uint16_t blockNum, uint16_t MultiBlockSize)
232 {
233 OADProtocol_Status_t status = OADProtocol_Failed;
234 uint8_t* pOadBlockReqPacket;
236 //Allocate the buffer
237 if(OADProtocol_params.pRadioAccessFxns->pfnRadioAccessAllocMsg)
238 {
239 pOadBlockReqPacket = OADProtocol_params.pRadioAccessFxns->pfnRadioAccessAllocMsg(
240 OADProtocol_PACKET_TYPE_OAD_BLOCK_REQ_LEN);
241 }
243 pOadBlockReqPacket[OADProtocol_PKT_CMDID_OFFSET] = OADProtocol_PACKET_TYPE_OAD_BLOCK_REQ;
245 pOadBlockReqPacket[OADProtocol_BLOCK_REQ_IMG_ID_OFFSET] = imgId;
247 pOadBlockReqPacket[OADProtocol_BLOCK_REQ_BLOCK_NUM_OFFSET] = blockNum & 0xFF;
248 pOadBlockReqPacket[OADProtocol_BLOCK_REQ_BLOCK_NUM_OFFSET + 1] = (blockNum >> 8) & 0xFF;
250 pOadBlockReqPacket[OADProtocol_BLOCK_REQ_MULTI_BLOCK_SIZE_OFFSET] = MultiBlockSize & 0xFF;
251 pOadBlockReqPacket[OADProtocol_BLOCK_REQ_MULTI_BLOCK_SIZE_OFFSET + 1] = (MultiBlockSize >> 8) & 0xFF;
253 if(OADProtocol_params.pRadioAccessFxns->pfnRadioAccessPacketSend)
254 {
255 status = OADProtocol_params.pRadioAccessFxns->pfnRadioAccessPacketSend(pDstAddress,
256 pOadBlockReqPacket,
257 OADProtocol_PACKET_TYPE_OAD_BLOCK_REQ_LEN);
258 }
260 return status;
261 }
263 OADProtocol_Status_t OADProtocol_sendOadImgBlockRsp(void* pDstAddress, uint8_t imgId, uint16_t blockNum, uint8_t *block)
264 {
266 OADProtocol_Status_t status = OADProtocol_Failed;
267 uint8_t* pOadBlockRspPacket;
269 //Allocate the buffer
270 if(OADProtocol_params.pRadioAccessFxns->pfnRadioAccessAllocMsg)
271 {
272 pOadBlockRspPacket = OADProtocol_params.pRadioAccessFxns->pfnRadioAccessAllocMsg(
273 OADProtocol_PACKET_TYPE_OAD_BLOCK_RSP_LEN);
274 }
276 pOadBlockRspPacket[OADProtocol_PKT_CMDID_OFFSET] = OADProtocol_PACKET_TYPE_OAD_BLOCK_RSP;
278 pOadBlockRspPacket[OADProtocol_BLOCK_RSP_IMG_ID_OFFSET] = imgId;
280 pOadBlockRspPacket[OADProtocol_BLOCK_RSP_BLOCK_NUM_OFFSET] = blockNum & 0xFF;
281 pOadBlockRspPacket[OADProtocol_BLOCK_RSP_BLOCK_NUM_OFFSET + 1] = (blockNum >> 8) & 0xFF;
283 memcpy(&(pOadBlockRspPacket[OADProtocol_BLOCK_RSP_BLOCK_DATA_OFFSET]), block, OAD_BLOCK_SIZE);
285 if(OADProtocol_params.pRadioAccessFxns->pfnRadioAccessPacketSend)
286 {
287 status = OADProtocol_params.pRadioAccessFxns->pfnRadioAccessPacketSend(pDstAddress,
288 pOadBlockRspPacket,
289 OADProtocol_PACKET_TYPE_OAD_BLOCK_RSP_LEN);
290 }
292 return status;
293 }
295 static OADProtocol_Status_t processFwVersioReq(void* pSrcAddress, uint8_t* pIncomingPacket)
296 {
297 OADProtocol_Status_t status = OADProtocol_Failed;
299 //call application callback
300 if(OADProtocol_params.pProtocolMsgCallbacks->pfnFwVersionReqCb != NULL)
301 {
302 OADProtocol_params.pProtocolMsgCallbacks->pfnFwVersionReqCb(pSrcAddress);
303 }
305 //TODO: process packet and send response if needed
306 status = OADProtocol_Status_Success;
308 return status;
309 }
311 static OADProtocol_Status_t processFwVersioRsp(void* pSrcAddress, uint8_t *pIncomingPacket)
312 {
313 OADProtocol_Status_t status = OADProtocol_Failed;
315 //call application callback
316 if(OADProtocol_params.pProtocolMsgCallbacks->pfnFwVersionRspCb != NULL)
317 {
318 OADProtocol_params.pProtocolMsgCallbacks->pfnFwVersionRspCb(pSrcAddress, (char*) &(pIncomingPacket[OADProtocol_VER_RSP_VERSIONSTRING_OFFSET]));
319 }
321 //TODO: process packet and send response if needed
322 status = OADProtocol_Status_Success;
324 return status;
325 }
327 static OADProtocol_Status_t processOadImgIdentifyReq(void* pSrcAddress, uint8_t *pIncomingPacket)
328 {
329 OADProtocol_Status_t status = OADProtocol_Failed;
331 //call application callback
332 if(OADProtocol_params.pProtocolMsgCallbacks->pfnOadImgIdentifyReqCb != NULL)
333 {
334 OADProtocol_params.pProtocolMsgCallbacks->pfnOadImgIdentifyReqCb(pSrcAddress,
335 pIncomingPacket[OADProtocol_IMG_IDENTIFY_REQ_IMG_ID_OFFSET],
336 &(pIncomingPacket[OADProtocol_IMG_IDENTIFY_REQ_IMG_HDR_OFFSET]));
337 }
339 //TODO: process packet and send response if needed
340 status = OADProtocol_Status_Success;
342 return status;
343 }
345 static OADProtocol_Status_t processOadImgIdentifyRsp(void* pSrcAddress, uint8_t *pIncomingPacket)
346 {
347 OADProtocol_Status_t status = OADProtocol_Failed;
349 //call application callback
350 if(OADProtocol_params.pProtocolMsgCallbacks->pfnOadImgIdentifyRspCb != NULL)
351 {
352 OADProtocol_params.pProtocolMsgCallbacks->pfnOadImgIdentifyRspCb(pSrcAddress,
353 pIncomingPacket[OADProtocol_IMG_IDENTIFY_RSP_STATUS_OFFSET]);
354 }
356 //TODO: process packet and send response if needed
357 status = OADProtocol_Status_Success;
359 return status;
360 }
362 static OADProtocol_Status_t processOadImgBlockReq(void* pSrcAddr, uint8_t *pIncomingPacket)
363 {
364 OADProtocol_Status_t status = OADProtocol_Failed;
366 uint8_t imgHdr = pIncomingPacket[OADProtocol_BLOCK_REQ_IMG_ID_OFFSET];
368 uint16_t blockNum = ( pIncomingPacket[OADProtocol_BLOCK_REQ_BLOCK_NUM_OFFSET] & 0xFF) |
369 ((pIncomingPacket[OADProtocol_BLOCK_REQ_BLOCK_NUM_OFFSET + 1] & 0xFF) << 8);
371 uint16_t multiBlockSize = ( pIncomingPacket[OADProtocol_BLOCK_REQ_MULTI_BLOCK_SIZE_OFFSET] & 0xFF) |
372 ((pIncomingPacket[OADProtocol_BLOCK_REQ_MULTI_BLOCK_SIZE_OFFSET + 1] & 0xFF) << 8);
374 //call application callback
375 if(OADProtocol_params.pProtocolMsgCallbacks->pfnOadBlockReqCb != NULL)
376 {
377 OADProtocol_params.pProtocolMsgCallbacks->pfnOadBlockReqCb(pSrcAddr, imgHdr, blockNum, multiBlockSize);
378 }
380 //TODO: process packet and send response if needed
381 status = OADProtocol_Status_Success;
383 return status;
384 }
386 static OADProtocol_Status_t processOadImgBlockRsp(void* pSrcAddress, uint8_t *pIncomingPacket)
387 {
388 OADProtocol_Status_t status = OADProtocol_Failed;
390 uint8_t imgHdr = pIncomingPacket[OADProtocol_BLOCK_RSP_IMG_ID_OFFSET];
392 uint16_t blockNum = ( pIncomingPacket[OADProtocol_BLOCK_RSP_BLOCK_NUM_OFFSET] & 0xFF) |
393 ((pIncomingPacket[OADProtocol_BLOCK_RSP_BLOCK_NUM_OFFSET + 1] & 0xFF) << 8);
395 //call application callback
396 if(OADProtocol_params.pProtocolMsgCallbacks->pfnOadBlockRspCb != NULL)
397 {
398 OADProtocol_params.pProtocolMsgCallbacks->pfnOadBlockRspCb(pSrcAddress,
399 imgHdr,
400 blockNum,
401 &(pIncomingPacket[OADProtocol_BLOCK_RSP_BLOCK_DATA_OFFSET]));
402 }
404 //TODO: process packet and send response if needed
405 status = OADProtocol_Status_Success;
407 return status;
408 }