1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 // Software and any modification/derivatives thereof.
18 // No right, ownership, or interest to MStar Software and any
19 // modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 // supplied together with third party`s software and the use of MStar
23 // Software may require additional licenses from third parties.
24 // Therefore, you hereby agree it is your sole responsibility to separately
25 // obtain any and all third party right and license necessary for your use of
26 // such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 // MStar`s confidential information and you agree to keep MStar`s
30 // confidential information in strictest confidence and not disclose to any
31 // third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 // kind. Any warranties are hereby expressly disclaimed by MStar, including
35 // without limitation, any warranties of merchantability, non-infringement of
36 // intellectual property rights, fitness for a particular purpose, error free
37 // and in conformity with any international standard. You agree to waive any
38 // claim against MStar for any loss, damage, cost or expense that you may
39 // incur related to your use of MStar Software.
40 // In no event shall MStar be liable for any direct, indirect, incidental or
41 // consequential damages, including without limitation, lost of profit or
42 // revenues, lost or damage of data, and unauthorized system use.
43 // You agree that this Section 4 shall still apply without being affected
44 // even if MStar Software has been modified by MStar in accordance with your
45 // request or instruction for your use, except otherwise agreed by both
46 // parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 // services in relation with MStar Software to you for your use of
50 // MStar Software in conjunction with your or your customer`s product
51 // ("Services").
52 // You understand and agree that, except otherwise agreed by both parties in
53 // writing, Services are provided on an "AS IS" basis and the warranty
54 // disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 // or otherwise:
58 // (a) conferring any license or right to use MStar name, trademark, service
59 // mark, symbol or any other identification;
60 // (b) obligating MStar or any of its affiliates to furnish any person,
61 // including without limitation, you and your customers, any assistance
62 // of any kind whatsoever, or any information; or
63 // (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 // of Taiwan, R.O.C., excluding its conflict of law rules.
67 // Any and all dispute arising out hereof or related hereto shall be finally
68 // settled by arbitration referred to the Chinese Arbitration Association,
69 // Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 // Rules of the Association by three (3) arbitrators appointed in accordance
71 // with the said Rules.
72 // The place of arbitration shall be in Taipei, Taiwan and the language shall
73 // be English.
74 // The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78
79 ////////////////////////////////////////////////////////////////////////////////
80 //
81 // Copyright (c) 2008-2009 MStar Semiconductor, Inc.
82 // All rights reserved.
83 //
84 // Unless otherwise stipulated in writing, any and all information contained
85 // herein regardless in any format shall remain the sole proprietary of
86 // MStar Semiconductor Inc. and be kept in strict confidence
87 // ("MStar Confidential Information") by the recipient.
88 // Any unauthorized act including without limitation unauthorized disclosure,
89 // copying, use, reproduction, sale, distribution, modification, disassembling,
90 // reverse engineering and compiling of the contents of MStar Confidential
91 // Information is unlawful and strictly prohibited. MStar hereby reserves the
92 // rights to any and all damages, losses, costs and expenses resulting therefrom.
93 //
94 ////////////////////////////////////////////////////////////////////////////////
95 #if defined (MSOS_TYPE_LINUX)
96 #include <stdio.h>
97 #include <stdlib.h>
98 #include <string.h>
99 #include <stddef.h>
100 #include <assert.h>
101 // ----------------------------------------------------------
102 // The Little-Endian and Big-Endian is ignor in the firmware,
103 // The PC-side client should take care of the tranfer data endian.
104 // ----------------------------------------------------------
105
106
107 /* According to earlier standards */
108 #include <unistd.h>
109 #include <fcntl.h>
110 #include <pthread.h>
111 #include <termios.h>
112
113 #include "apiHSL.h"
114 #include "frhsl_datalink.h"
115 #include "frhsl_autotest.h"
116 #include "apiHSL_SHM.h"
117 #include "frhsl_cfg.h"
118
119 #ifdef HSL_TCPIP
120 #include <sys/socket.h>
121 #include <errno.h>
122 #include <netinet/in.h>
123 #include <arpa/inet.h>
124
125 #define LENGTH_OF_LISTEN_QUEUE 50 //length of listen queue in server
126 #define DBG_OUTPUT_TCPIP 0
127 #define DBG_OUTPUT_FILE 0
128
129 #define HSL_DBG_OUTPUT_FILE "/utopia_test/HSL_Log"
130 #define MSG_RESPONSE_OVERFLOW "Invalid AT response length specified which exceeds %u char"
131
132 #endif
133
134 //#define HSL_FILE_MSG(FILE_NAME, fmt, arg...) printf(fmt, ##arg)
135 #define HSL_FILE_MSG(FILE_NAME, fmt, arg...)
136
137
138 FILE *OutputFp;
139 cHslSyncMem hslSyncMem;
140
141 static void CmdRecvStart(p_HslController _hsl);
142
143 // =============================
144 // For AutoTest
145 // =============================
146
InitThread(void * pHsl)147 static void* InitThread(void* pHsl)
148 {
149 p_HslController hsl = (p_HslController)pHsl;
150 CmdRecvStart(hsl) ;
151 return NULL;
152 }
153
154 #define SET_RESP_DWORD(buffer, index, value) \
155 *((MS_U32*)(buffer+LINK_HEADER_SIZE+4*index)) = value
156
157
158
CmdSend(stHslController * const _hsl,const void * message,int length)159 void CmdSend(stHslController* const _hsl, const void *message, int length)
160 {
161 send(_hsl->hClientSocket,message,length,0);
162 }
163
SendMessage(p_HslController _hsl,void * a_pBody,int a_bodySize)164 MS_BOOL SendMessage(p_HslController _hsl, void *a_pBody, int a_bodySize)
165 {
166 CmdInfo rb_cmd;
167
168 rb_cmd.u32Pid = 0x12345678; // test
169 rb_cmd.u16Cmd = (MS_U16)HSL_CMD_SEND_DATA;
170 rb_cmd.u32Len = a_bodySize;
171 rb_cmd.pu8Buf = a_pBody;
172
173 return FrHslCommand(_hsl, &rb_cmd);
174 }
175
RespCardStatus(p_HslController _hsl,MS_U8 * a_buffer)176 MS_BOOL RespCardStatus(p_HslController _hsl, MS_U8 *a_buffer)
177 {
178 /* TP: Need to add some error notification for the pc.
179 * At the moment if anything goes wrong this function
180 * aborts and quietly returns FALSE causing a timeout
181 * on the PC. Let's assume that a response of (0,0)
182 * will mean a problem with retrieving data from the RB.
183 */
184
185 CmdInfo rb_cmd;
186 MS_BOOL bRetn = FALSE;
187
188 MS_U32 totalSize = 0;
189 MS_U32 usedSize = 0;
190
191 // -----------------------------------------------
192 // get Total size
193 // -----------------------------------------------
194 rb_cmd.u32Pid = 0x12345678; // test -- is it still needed (TP)?
195
196 rb_cmd.u16Cmd = HSL_CMD_RB_TOTAL_SIZE;
197 rb_cmd.pu8Buf = NULL;
198 rb_cmd.u32Len = 0; // put the size in here
199
200 if( FrHslCommand(_hsl, &rb_cmd) )
201 {
202 totalSize = rb_cmd.u32Len;
203
204 // -----------------------------------------------
205 // get Used size
206 // -----------------------------------------------
207 rb_cmd.u16Cmd = HSL_CMD_RB_EXIST_DATA_SIZE;
208 rb_cmd.u32Len = 0; // put the size in here
209 if( FrHslCommand(_hsl, &rb_cmd) )
210 {
211 usedSize = rb_cmd.u32Len;
212 bRetn = TRUE;
213 }
214 }
215
216 // -----------------------------------------------
217 // detect error
218 // -----------------------------------------------
219 if((usedSize > totalSize) && (usedSize != 0xffffffff))
220 {
221 // body.usedSize = body.totalSize / 2; // TP: why was this necessary?
222 HSL_FILE_MSG(OutputFp, "Ring buffer internal error\n");
223 bRetn = FALSE;
224 }
225
226 // -----------------------------------------------
227 // send Response
228 // -----------------------------------------------
229 if( bRetn != TRUE )
230 {
231 usedSize = totalSize = 0; // clear any rubbish
232 }
233
234 a_buffer[0] = (MS_U8)EN_LINK_CMD_RESP_CARD_STATUS;
235 // seqNo should remain the same as in the received message
236
237 SET_RESP_DWORD(a_buffer, 0, usedSize);
238 SET_RESP_DWORD(a_buffer, 1, totalSize);
239
240 bRetn &= SendMessage(_hsl, a_buffer, LINK_HEADER_SIZE+LINK_DATA_RESPONSE_CARD_STATUS);
241
242 //HSL_FILE_MSG(OutputFp, "Used_Size:%lx RingBuf_Size:%lx\n", body.usedSize, body.totalSize);
243 // HSL_FILE_MSG(OutputFp, "CardStatus=%x/%x\n", usedSize, totalSize);
244
245 return bRetn;
246 }
247
RespHslData(p_HslController _hsl,MS_U8 * a_buffer)248 MS_BOOL RespHslData(p_HslController _hsl, MS_U8 *a_buffer)
249 {
250 MS_BOOL bRetn = FALSE;
251 int blength;
252
253 CmdInfo rb_cmd;
254
255 // -----------------------------------------------
256 // recv "Request Size"
257 // -----------------------------------------------
258 blength = recv(_hsl->hClientSocket, a_buffer+LINK_HEADER_SIZE, LINK_DATA_GET_HSL_DATA, 0);
259 if (blength == 0)
260 {
261 HSL_FILE_MSG(OutputFp,"Client connection has been closed.\n");
262 return FALSE;
263 }
264
265 MS_U32 reqSize = *((MS_U32*)(a_buffer+LINK_HEADER_SIZE));
266 //HSL_FILE_MSG(OutputFp, "RequestSize : %lx\n", reqSize);
267
268 // -----------------------------------------------
269 // get Used size
270 // -----------------------------------------------
271
272 rb_cmd.u16Cmd = HSL_CMD_RB_EXIST_DATA_SIZE;
273 rb_cmd.u32Len = 0; // put the size in here
274 bRetn = FrHslCommand(_hsl, &rb_cmd);
275 if( !bRetn )
276 {
277 return FALSE;
278 }
279 MS_U32 usedSize = rb_cmd.u32Len;
280
281 // -----------------------------------------------
282 // Decide bytes send back
283 // -----------------------------------------------
284 if( reqSize > usedSize)
285 {
286 reqSize = usedSize;
287 HSL_FILE_MSG(OutputFp, "RealSize : %lx\n", reqSize);
288 }
289
290 // -----------------------------------------------
291 // Send "Response CMD"
292 // -----------------------------------------------
293
294 //TODO: Check if the requested data is still available in the ringbuffer
295 /* (TP) By the look of it it is always attempted to send exactly the requested amount
296 * of data from the ringbuffer. Could see no query to the RB if such amount is available.
297 * will leave it like this for now but it must be addressed before release.
298 */
299
300 a_buffer[0] = (MS_U8)EN_LINK_CMD_RESP_HSL_DATA; // only need to change the cmd id in this case
301 SET_RESP_DWORD(a_buffer, 0, reqSize);
302
303 bRetn = SendMessage(_hsl, a_buffer, LINK_HEADER_SIZE+LINK_DATA_RESPONSE_HSL_CMD);
304
305 if( bRetn)
306 {
307 // -----------------------------------------------
308 // pop Data
309 // -----------------------------------------------
310 // HSL_FILE_MSG(OutputFp, "Start to send packet type 4, request size:%x.\n", reqStru.reqSize);
311 rb_cmd.u32Pid = 0; // test
312 rb_cmd.u16Cmd = HSL_CMD_GET_HSL_DATA;
313 rb_cmd.u32Len = reqSize;
314 rb_cmd.pu8Buf = NULL;
315
316 bRetn = FrHslCommand(_hsl, &rb_cmd);
317 }
318
319 return bRetn;
320 }
321
ProcessCmd(p_HslController _hsl,MS_U8 * a_cmdBuffer)322 MS_U32 ProcessCmd(p_HslController _hsl, MS_U8 *a_cmdBuffer)
323 {
324 MS_U32 errCode = EN_CMD_EC_OK;
325 int i = 0;
326
327 // At this point we assume that the PC has sent all the data in
328 // and cast the buffer onto a command structure
329 ST_HSL_CMD_REQ* p_command = (ST_HSL_CMD_REQ*)a_cmdBuffer;
330
331 HSL_FILE_MSG(OutputFp,"CmdId=%X, Ver=%X\n", p_command->cmdId, p_command->ver);
332
333 if( p_command->ver != LINK_PROTOCOL_VERSION )
334 {
335 errCode = EN_CMD_EC_VERSION;
336 }
337 else
338 {
339 switch( p_command->cmdId )
340 {
341 case EN_CMD_TEST_NONE:
342 errCode = EN_CMD_EC_CMD_UNKNOWN;
343 break;
344 case EN_CMD_TEST_AT:
345 if( !StoreShareMemory(&hslSyncMem, p_command->U_Cmd.atCmd) )
346 {
347 errCode = EN_CMD_EC_AT_FAILURE;
348 PackAtCmdEchoIntoHslCmdResp(false, p_command->U_Cmd.atCmd);
349 }
350 else
351 {
352 PackAtCmdEchoIntoHslCmdResp(true, p_command->U_Cmd.atCmd);
353 }
354 break;
355 case EN_CMD_TEST_LOAD:
356 {
357 HSL_FILE_MSG(OutputFp, "Load Test request received\n");
358 gRunLoadTest = true;
359 for(i=0; i<p_command->U_Cmd.loadTestCmd.mThreadNo; i++)
360 {
361 if( 0 != pthread_create(&gTestThreads[i], 0, HslSelfTestThreadFun, (void*)(&p_command->U_Cmd.loadTestCmd) ) )
362 {
363 HSL_FILE_MSG(OutputFp, "Failed to create thread! Stop the load test\n");
364 errCode = EN_CMD_EC_THREAD_FAIL;
365 gRunLoadTest = false;
366 break;
367 }
368 else
369 {
370 HSL_FILE_MSG(OutputFp, "Load test thread %d created\n", i);
371 }
372 }
373
374 }
375 break;
376 default:
377 errCode = EN_CMD_EC_CMD_UNKNOWN;
378 break;
379 }
380 }
381
382 return errCode;
383 }
384
385 /** Wrapper function to echo back input AT command back to PC.
386 This is done to permit to get an exact timestamp on when the command was processed. */
PackAtCmdEchoIntoHslCmdResp(MS_BOOL a_result,const char * a_atCmd)387 void PackAtCmdEchoIntoHslCmdResp(MS_BOOL a_result, const char* a_atCmd)
388 {
389 AtCmdEcho obj;
390 obj.result = a_result;
391 memset(obj.atCmd, '\0', sizeof(obj.atCmd));
392 strncpy(obj.atCmd, a_atCmd, sizeof(obj.atCmd) - 1);
393 PackIntoHslCmdResp(EN_RESP_TEST_AT_ECHO, (const void*)&obj);
394 }
395
396
397 /** Wrapper function for sending AT command response back to PC */
PackAtRespIntoHslCmdResp(const char * a_atResp)398 void PackAtRespIntoHslCmdResp(const char* a_atResp)
399 {
400 PackIntoHslCmdResp(EN_RESP_TEST_AT, (const void*)a_atResp);
401 }
402
403
404 /** Wrapper function to transport over log point id 0x000A the Hsl Command response
405 * The implementation depends closely on the definition of ST_HSL_CMD_RESP; Any
406 * update to that structure would need to be reflected here. */
PackIntoHslCmdResp(EN_RESPONSE_ID a_respId,const void * a_body)407 void PackIntoHslCmdResp(EN_RESPONSE_ID a_respId, const void* a_body)
408 {
409 MS_U16 packedStructLength = offsetof(ST_HSL_CMD_RESP, U_Resp); /* This gets the total size up to the start of the union. */
410
411 ST_HSL_CMD_RESP container;
412
413 container.respId = a_respId;
414
415 switch (a_respId)
416 {
417 case EN_RESP_TEST_AT:
418 {
419 MS_U32 strLength = strlen((const char*)a_body) + 1; /* +1 for the null char as this is a string */
420 if (strLength > RSP_MAX_AT)
421 {
422 snprintf(container.U_Resp.atResponse, strlen(MSG_RESPONSE_OVERFLOW)+10,MSG_RESPONSE_OVERFLOW, RSP_MAX_AT);
423 packedStructLength += (MS_U16)(strlen(container.U_Resp.atResponse) + 1);
424 }
425 else
426 {
427 strncpy(container.U_Resp.atResponse, (char*) a_body,strLength);
428 packedStructLength += (MS_U16)strLength;
429 }
430 }
431 break;
432
433 case EN_RESP_TEST_AT_ECHO:
434 {
435 const AtCmdEcho* cmdEchoPtr = (const AtCmdEcho*) a_body;
436 container.U_Resp.atCmdEcho.result = (MS_BOOL) (cmdEchoPtr->result);
437
438 MS_U32 strLength = strlen((const char*)cmdEchoPtr->atCmd) + 1; /* +1 for the null char as this is a string */
439 if (strLength > CMD_MAX_AT)
440 {
441 snprintf(container.U_Resp.atCmdEcho.atCmd, strlen(MSG_RESPONSE_OVERFLOW)+10,MSG_RESPONSE_OVERFLOW, CMD_MAX_AT);
442 packedStructLength += (MS_U16)(strlen(container.U_Resp.atCmdEcho.atCmd) + 1);
443 }
444 else
445 {
446 strncpy(container.U_Resp.atCmdEcho.atCmd, (char*) cmdEchoPtr->atCmd,strLength);
447 packedStructLength += (MS_U16)strLength;
448 }
449
450 }
451 break;
452
453 case EN_RESP_TEST_CMD_LAST:
454 break;
455
456 default:
457 break;
458 }
459
460 if ((packedStructLength % 2) == 1)
461 {
462 packedStructLength += (MS_U16)1; // This ensures we don't lose one character as we transfer in MS_U16 blocks over HSL.
463 }
464
465 HSL_FILE_MSG(OutputFp,"Length=%d\n", packedStructLength);
466
467 /* Using hard coded log point ID for this structure; Do not modify this log point ID as tools
468 * on PC depend on it. */
469 M_FrHslArray16(0x000A, HSL_DBG_UTOPIA_ALL_DEBUG, "ST_HSL_CMD_RESP: %#04X", packedStructLength/sizeof(MS_U16), &container);
470
471 }
472
473 // -----------------------------------------------
474 // Process HSL command
475 // If error occured and can not be recovered, return false
476 // This connection should be closed
477 // -----------------------------------------------
RespHslCmd(p_HslController _hsl,MS_U8 * a_buffer)478 MS_BOOL RespHslCmd(p_HslController _hsl, MS_U8 *a_buffer)
479 {
480 int bLength = 0;
481 int bReceived = 0;
482 MS_U8 cmdBuffer[LINK_MAX_COMMAND];
483 MS_BOOL bRetn = FALSE;
484 MS_U32 errCode = EN_CMD_EC_OK;
485
486 //----------------------------------
487 // Read "len" field first
488 //----------------------------------
489 bLength = recv(_hsl->hClientSocket, a_buffer+LINK_HEADER_SIZE, LINK_DATA_SEND_HSL_CMD, 0);
490 if (bLength == 0)
491 {
492 HSL_FILE_MSG(OutputFp,"Client connection has been closed.\n");
493 return FALSE;
494 }
495 else
496 {
497 bRetn = TRUE;
498 }
499
500 //----------------------------------
501 // Read all payload after "len"
502 //----------------------------------
503 MS_U32 reqLen = *((MS_U32*)(a_buffer+LINK_HEADER_SIZE));
504 if( reqLen > LINK_MAX_COMMAND )
505 {
506 // No recovery - in case of failure everything should shutdown
507 errCode = EN_CMD_EC_DATA_SIZE;
508 HSL_FILE_MSG(OutputFp, "Command received, wrong size: %u is not < %u\n", (unsigned int)reqLen, LINK_MAX_COMMAND);
509 }
510 else
511 {
512 // Read the whole message - may come in one or more pieces
513 bReceived = 0;
514 while( bReceived < reqLen )
515 {
516 //TODO!: add timeout handling
517 bLength = recv(_hsl->hClientSocket, (char*)(cmdBuffer+bReceived), reqLen-bReceived, 0);
518 bReceived += bLength;
519 }
520 errCode = ProcessCmd(_hsl, cmdBuffer);
521 }
522
523 a_buffer[0] = (MS_U8)EN_LINK_CMD_RESP_HSL_CMD;
524 SET_RESP_DWORD(a_buffer, 0, errCode);
525
526 // bRetn = (errCode == EN_CMD_EC_OK); // All or nothing, in case of error close the connection
527 bRetn &= SendMessage(_hsl, a_buffer, LINK_HEADER_SIZE+LINK_DATA_RESPONSE_HSL_CMD);
528 HSL_FILE_MSG(OutputFp, "After processing a command: err code: %u, result: %d\n", (unsigned int)errCode, (int)bRetn);
529 return bRetn;
530 }
531
532
RespFilterMx(p_HslController _hsl,MS_U8 * a_buffer)533 MS_BOOL RespFilterMx(p_HslController _hsl, MS_U8 * a_buffer)
534 {
535 int bLength = 0;
536 int bReceived = 0;
537 MS_U8 cmdBuffer[CMD_MAX_FILTER];
538 MS_BOOL bRetn = FALSE;
539 MS_U32 errCode = EN_CMD_EC_OK;
540
541 //----------------------------------
542 // Read "len" field first
543 //----------------------------------
544 bLength = recv(_hsl->hClientSocket, a_buffer+LINK_HEADER_SIZE, LINK_DATA_SEND_HSL_CMD, 0);
545 if (bLength == 0)
546 {
547 HSL_FILE_MSG(OutputFp,"Client connection has been closed.\n");
548 return FALSE;
549 }
550
551 //----------------------------------
552 // Read all payload after "len"
553 //----------------------------------
554 MS_U32 reqLen = *((MS_U32*)(a_buffer+LINK_HEADER_SIZE));
555 if( reqLen > CMD_MAX_FILTER )
556 {
557 // No recovery - in case of failure everything should shutdown
558 errCode = EN_CMD_EC_DATA_SIZE;
559 }
560 else
561 {
562 // Read the whole message - may come in one or more pieces
563 bReceived = 0;
564 while( bReceived < reqLen )
565 {
566 bLength = recv(_hsl->hClientSocket, (char*)(cmdBuffer+bReceived), reqLen-bReceived, 0);
567 bReceived += bLength;
568 }
569 //errCode = ProcessCmd(cmdBuffer);
570 KiTtiProcessSetsFilter((KiSetsFilterMatrix*)cmdBuffer);
571 }
572
573 a_buffer[0] = (MS_U8)EN_LINK_CMD_RSP_FILTER_MX;
574 SET_RESP_DWORD(a_buffer, 0, errCode);
575
576 HSL_FILE_MSG(OutputFp,"reqLen=%lx, errCode=%lx\n", reqLen, errCode);
577
578 bRetn = (errCode == EN_CMD_EC_OK); // All or nothing, in case of error close the connection
579 bRetn &= SendMessage(_hsl, a_buffer, LINK_HEADER_SIZE+LINK_DATA_RESPONSE_HSL_CMD);
580 return bRetn;
581 }
582
583 // -----------------------------------------------
584 // Thread Start Function
585 // -----------------------------------------------
CmdRecvStart(p_HslController _hsl)586 static void CmdRecvStart(p_HslController _hsl)
587 {
588 struct sockaddr_in servaddr;
589 struct sockaddr_in cliaddr;
590 socklen_t socklen;
591 int blength;
592 struct timeval tv;
593 int iResult;
594
595 MS_BOOL bRetn = FALSE;
596 //string output;
597 //long timestamp;
598
599 // -----------------------------------------------
600 // Initial
601 // -----------------------------------------------
602
603 assert(_hsl!=0);
604
605 blength = 0;
606 bRetn = true;
607
608 socklen = sizeof(cliaddr);
609
610 bzero(&servaddr,sizeof(servaddr));
611 servaddr.sin_family = AF_INET;
612 servaddr.sin_port = htons(_hsl->u32Port);
613 servaddr.sin_addr.s_addr = htons(INADDR_ANY);
614
615 #if DBG_OUTPUT_FILE
616 OutputFp = fopen(HSL_DBG_OUTPUT_FILE,"w+");
617 fclose(OutputFp);
618 #endif
619
620 // -----------------------------------------------
621 // listen port
622 // -----------------------------------------------
623 HSL_FILE_MSG(OutputFp,"HSL: create socket!\n");
624 _hsl->hServerSocket = socket(AF_INET,SOCK_STREAM,0);
625 if (_hsl->hServerSocket < 0)
626 {
627 HSL_FILE_MSG(OutputFp,"create socket error!\n");
628 return;
629 }
630
631 HSL_FILE_MSG(OutputFp, "HSL: bind to port %u!\n", (unsigned int)_hsl->u32Port);
632 iResult = bind(_hsl->hServerSocket, (struct sockaddr*)&servaddr, sizeof(servaddr));
633 if (iResult < 0)
634 {
635 HSL_FILE_MSG(OutputFp, "HSL: bind to port %u failure!\n", (unsigned int)_hsl->u32Port);
636 return;
637 }
638
639 HSL_FILE_MSG(OutputFp,"HSL: call listen!\n");
640 if (listen(_hsl->hServerSocket,LENGTH_OF_LISTEN_QUEUE) < 0)
641 {
642 HSL_FILE_MSG(OutputFp,"HSL: call listen failure!\n");
643 return;
644 }
645
646 HSL_FILE_MSG(OutputFp,"HSL: Start to accept socket connection.\n");
647
648 if(_hsl->u8Instance == 0 )
649 {
650 if( false == InitShareMemory(&hslSyncMem, true))
651 {
652 HSL_FILE_MSG(OutputFp,"HSL: InitShareMemory() error!\n");
653 return;
654 }
655 HSL_FILE_MSG(OutputFp,"HSL: InitShareMemory() successful!\n");
656 }
657
658 HSL_FILE_MSG(OutputFp,"HSL: check if flash ok, before while(1)\n");
659
660 // -----------------------------------------------
661 // set timeout
662 // -----------------------------------------------
663
664 tv.tv_sec = LINK_CONNECTION_TIMEOUT;
665 tv.tv_usec = 0;
666 if(setsockopt(_hsl->hServerSocket, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *)&tv, sizeof(struct timeval)) < 0)
667 {
668 HSL_FILE_MSG(OutputFp,"HSL: setsockopt error!\n");
669 return;
670 }
671
672 // -----------------------------------------------
673 // process data
674 // -----------------------------------------------
675 MS_U8 socketBuffer[LINK_BUFFER_SIZE];
676 pthread_mutex_lock(&(_hsl->socketReadMutex));
677
678 while(_hsl->g_AutoTestRun)
679 {
680 // -----------------------------------------------
681 // accept()
682 // -----------------------------------------------
683 HSL_FILE_MSG(OutputFp, "HSL: Waiting for an access to the RCV loop\n");
684 while(_hsl->g_AutoTestRun)
685 {
686 _hsl->hClientSocket = accept(_hsl->hServerSocket, (struct sockaddr*)&cliaddr, &socklen);
687 if( _hsl->hClientSocket >= 0)
688 {
689 FrHslResetConnection(_hsl); // when new connection come, reset it
690 bRetn = TRUE;
691 break;
692 }
693 else
694 {
695 HSL_FILE_MSG(OutputFp, "HSL: Socket not connected: errno=%d ", errno);
696 if( errno == 11 )
697 {
698 HSL_FILE_MSG(OutputFp, "(Try again)\n");
699 }
700 else
701 {
702 HSL_FILE_MSG(OutputFp, "\n");
703 }
704 }
705 errno = 0;
706 }
707
708 HSL_FILE_MSG(OutputFp,"HSL: Accepted connection from client,IP:%s,Port:%d\n",inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port));
709
710 while((_hsl->hClientSocket >= 0) && (_hsl->g_AutoTestRun))
711 {
712 // -----------------------------------------------
713 // Receive packet header: Command(1 byte) and Sequence Number (1 byte)
714 // -----------------------------------------------
715
716 // The return value will be 0 when the peer has performed an orderly shutdown and errno == 0
717 blength = recv(_hsl->hClientSocket, socketBuffer, LINK_HEADER_SIZE, 0);
718 if (blength > 0)
719 {
720 // HSL_FILE_MSG(OutputFp, "HSL: Received %d bytes\n", blength);
721 bRetn = TRUE;
722 }
723 else if(blength == 0)
724 {
725 HSL_FILE_MSG(OutputFp, "HSL: Connection closed by client\n");
726 bRetn = FALSE;
727 }
728 else // blength <= 0
729 {
730 HSL_FILE_MSG(OutputFp, "HSL: Socket error: %d\n", errno);
731 bRetn = FALSE;
732 }
733
734 if(bRetn != FALSE)
735 {
736 MS_U8 cmdId = socketBuffer[0];
737
738 switch(cmdId)
739 {
740 case EN_LINK_CMD_GET_CARD_STATUS:
741 bRetn = RespCardStatus(_hsl, socketBuffer);
742 break;
743
744 case EN_LINK_CMD_GET_HSL_DATA:
745 bRetn = RespHslData(_hsl, socketBuffer);
746 break;
747
748 case EN_LINK_CMD_SEND_HSL_CMD:
749 bRetn = RespHslCmd(_hsl, socketBuffer);
750 break;
751
752 case EN_LINK_CMD_SND_FILTER_MX:
753 bRetn = RespFilterMx(_hsl ,socketBuffer);
754 break;
755
756 default:
757 //TODO: need to think if any feedback to the pc is required
758 bRetn = false;
759 HSL_FILE_MSG(OutputFp, "HSL: ERROR: Unknown command!\n");
760 break;
761 }
762 // HSL_FILE_MSG(OutputFp,"HSL: Finished processing a command\n");
763 }
764 else
765 {
766 HSL_FILE_MSG(OutputFp,"HSL: Connection closed or HSL transport layer failure\n");
767 break; // ToDo: uncomment it, if teraHSL can create new clifd
768 // TP: if the protocol is broken for some reason there is no point
769 // in keeping the connection alive. If TeraHSL cannot cope with it
770 // it's should not compromise the implementation on the target.
771 }
772 }
773 if (_hsl->hClientSocket >=0)
774 {
775 HSL_FILE_MSG(OutputFp,"HSL: Closing client socket %d\n", _hsl->hClientSocket);
776 close(_hsl->hClientSocket);
777 }
778 else
779 {
780 printf("HSL: ERROR: Invalid id when attempting to close a socket (%d)\n", _hsl->hClientSocket);
781 }
782 }
783
784 pthread_mutex_unlock(&(_hsl->socketReadMutex));
785 close(_hsl->hServerSocket);
786 FreeShareMemory(&hslSyncMem);
787
788 return;
789 }
790
FrHsl_AutoTest_Init(stHslController * const _hsl)791 MS_BOOL FrHsl_AutoTest_Init(stHslController* const _hsl)
792 {
793 pthread_attr_t attr;
794 pthread_attr_init(&attr);
795
796 _hsl->g_AutoTestRun = true;
797 if(!pthread_create(&(_hsl->threadCmdRecvStart), &attr, InitThread, _hsl))
798 return true;
799 else
800 return false;
801 }
802
FrHsl_AutoTest_End(stHslController * const _hsl)803 void FrHsl_AutoTest_End(stHslController* const _hsl)
804 {
805 _hsl->g_AutoTestRun = false;
806 if( 0 != pthread_join(_hsl->threadCmdRecvStart, 0))
807 {
808 HSL_FILE_MSG(OutputFp, "ERROR: Failed to shutdown the HSL receive thread!\n");
809 }
810 }
811
812 #endif
813 /* END OF FILE */
814
815