00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include <stdio.h>
00047 #include <stdlib.h>
00048 #include <string.h>
00049
00050 #include "rnr/rnrconfig.h"
00051 #include "rnr/log.h"
00052 #include "rnr/opts.h"
00053 #include "rnr/new.h"
00054 #include "rnr/sock.h"
00055 #include "rnr/char.h"
00056
00057 #include "botsense/bsproxy_if.h"
00058
00059 #include "version.h"
00060 #include "bsproxy.h"
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 static int ClientDevFindEmptySlot(BsProxyClient_T *pClient)
00075 {
00076 int i;
00077
00078 for(i=0; i<BSPROXY_CLIENT_DEV_MAX; ++i)
00079 {
00080 if( pClient->m_tblClientDev[i].m_eDevType == BSPROXY_DEVTYPE_NONE )
00081 {
00082 return i;
00083 }
00084 }
00085 return -1;
00086 }
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 static int ClientSendHdrError(BsProxyClient_T *pClient,
00098 byte_t bufCmd[], size_t lenCmd)
00099 {
00100 byte_t buf[BSPROXY_CMD_HDR_LEN];
00101
00102 switch( lenCmd )
00103 {
00104 case 0:
00105 buf[BSPROXY_CMD_HDR_MSGID_IDX] = BSPROXY_MSGID_ERROR;
00106 buf[BSPROXY_CMD_HDR_TID_IDX] = 0;
00107 buf[BSPROXY_CMD_HDR_BLEN_IDX] = 0;
00108 return ClientSendFailRsp(pClient, buf, "no command header");
00109 case 1:
00110 buf[BSPROXY_CMD_HDR_MSGID_IDX] = bufCmd[BSPROXY_CMD_HDR_MSGID_IDX];
00111 buf[BSPROXY_CMD_HDR_TID_IDX] = 0;
00112 buf[BSPROXY_CMD_HDR_BLEN_IDX] = 0;
00113 return ClientSendFailRsp(pClient, buf, "bad header - no transation id");
00114 case 2:
00115 default:
00116 buf[BSPROXY_CMD_HDR_MSGID_IDX] = bufCmd[BSPROXY_CMD_HDR_MSGID_IDX];
00117 buf[BSPROXY_CMD_HDR_TID_IDX] = bufCmd[BSPROXY_CMD_HDR_TID_IDX];
00118 buf[BSPROXY_CMD_HDR_BLEN_IDX] = 0;
00119 return ClientSendFailRsp(pClient, buf, "bad header - no body length");
00120 }
00121 }
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 static int ClientGetHandle(BsProxyClient_T *pClient, byte_t bufCmd[])
00136 {
00137 int nHandle;
00138
00139 chkCmdBLenGE(pClient, bufCmd, 1);
00140
00141 nHandle = (int)bufCmd[BSPROXY_CMD_HDR_LEN];
00142
00143 if( (nHandle < 0) || (nHandle >= BSPROXY_CLIENT_DEV_MAX) )
00144 {
00145 LOGERROR("%s: %d: device handle out of range.",
00146 pClient->m_sClientName, nHandle);
00147 return ClientSendFailRsp(pClient, bufCmd, "bad parameter");
00148 }
00149
00150 if( pClient->m_tblClientDev[nHandle].m_eDevType == BSPROXY_DEVTYPE_NONE )
00151 {
00152 LOGERROR("%s: %d: no proxied device.", pClient->m_sClientName, nHandle);
00153 return ClientSendFailRsp(pClient, bufCmd, "no proxied device");
00154 }
00155
00156 return nHandle;
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 static int CmdLoopback(BsProxyServer_T *pServer,
00182 BsProxyClient_T *pClient,
00183 byte_t bufCmd[], size_t lenCmd)
00184 {
00185 byte_t bufRsp[BSPROXY_MSG_MAX_LEN];
00186 size_t lenBody;
00187
00188 BSPROXY_LOG_CMD(pClient, bufCmd, lenCmd);
00189
00190 lenBody = bufCmd[BSPROXY_CMD_HDR_BLEN_IDX];
00191
00192 if( lenBody > BSPROXY_RSP_BODY_LEN_MAX )
00193 {
00194 lenBody = BSPROXY_RSP_BODY_LEN_MAX;
00195 }
00196
00197 fprintf(stderr, "%s: ", pClient->m_sClientName);
00198 PrettyPrintBuf(stderr, &bufCmd[BSPROXY_CMD_HDR_LEN],
00199 lenCmd-BSPROXY_CMD_HDR_LEN);
00200 fprintf(stderr, "\n");
00201
00202
00203 memcpy(bufRsp+BSPROXY_RSP_HDR_LEN, bufCmd+BSPROXY_CMD_HDR_LEN, lenBody);
00204
00205 return ClientSendPassRsp(pClient, bufCmd, bufRsp,
00206 BSPROXY_RSP_HDR_LEN+lenBody);
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 static int CmdLog(BsProxyServer_T *pServer,
00227 BsProxyClient_T *pClient,
00228 byte_t bufCmd[], size_t lenCmd)
00229 {
00230 byte_t bufRsp[BSPROXY_MSG_MAX_LEN];
00231 size_t lenRsp;
00232 int nLevel;
00233
00234 BSPROXY_LOG_CMD(pClient, bufCmd, lenCmd);
00235
00236 chkCmdBLenEQ(pClient, bufCmd, 1);
00237
00238 nLevel = (int)bufCmd[BSPROXY_CMD_HDR_LEN];
00239
00240 nLevel = LOG_SET_THRESHOLD(nLevel);
00241
00242 lenRsp = BSPROXY_RSP_HDR_LEN;
00243 bufRsp[lenRsp++] = (byte_t)nLevel;
00244
00245 return ClientSendPassRsp(pClient, bufCmd, bufRsp, lenRsp);
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 static int CmdVersion(BsProxyServer_T *pServer,
00266 BsProxyClient_T *pClient,
00267 byte_t bufCmd[], size_t lenCmd)
00268 {
00269 byte_t bufRsp[BSPROXY_MSG_MAX_LEN];
00270 size_t lenRsp;
00271 char *sVersion;
00272
00273 BSPROXY_LOG_CMD(pClient, bufCmd, lenCmd);
00274
00275 lenRsp = BSPROXY_RSP_HDR_LEN;
00276
00277 sVersion = (char *)&bufRsp[lenRsp];
00278
00279 snprintf(sVersion, (size_t)(BSPROXY_CMD_HDR_LEN-BSPROXY_RSP_HDR_LEN),
00280 "bsproxy %s %s", PKG_VERSION, PKG_TIMESTAMP);
00281
00282 sVersion[BSPROXY_CMD_HDR_LEN-BSPROXY_RSP_HDR_LEN-1] = 0;
00283
00284 lenRsp += strlen(sVersion) + 1;
00285
00286 return ClientSendPassRsp(pClient, bufCmd, bufRsp, lenRsp);
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 static int CmdProxyInfo(BsProxyServer_T *pServer,
00307 BsProxyClient_T *pClient,
00308 byte_t bufCmd[], size_t lenCmd)
00309 {
00310 byte_t bufRsp[BSPROXY_MSG_MAX_LEN];
00311 size_t lenRsp;
00312
00313 BSPROXY_LOG_CMD(pClient, bufCmd, lenCmd);
00314
00315 lenRsp = BSPROXY_RSP_HDR_LEN;
00316 bufRsp[lenRsp++] = (byte_t)BSPROXY_DEVTYPE_I2C;
00317 bufRsp[lenRsp++] = (byte_t)BSPROXY_DEVTYPE_BPFOOT;
00318 bufRsp[lenRsp++] = (byte_t)BSPROXY_DEVTYPE_BPIMU;
00319 bufRsp[lenRsp++] = (byte_t)BSPROXY_DEVTYPE_RCB3;
00320
00321 return ClientSendPassRsp(pClient, bufCmd, bufRsp, lenRsp);
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 static int CmdDevOpen(BsProxyServer_T *pServer,
00348 BsProxyClient_T *pClient,
00349 byte_t bufCmd[], size_t lenCmd)
00350 {
00351 byte_t bufRsp[BSPROXY_MSG_MAX_LEN];
00352 size_t lenRsp;
00353 size_t n;
00354 byte_t eDevType;
00355 byte_t i2cAddr;
00356 char *sDevName;
00357 BsProxyDev_T *pProxDev;
00358 int nHandle;
00359
00360 BSPROXY_LOG_CMD(pClient, bufCmd, lenCmd);
00361
00362 chkCmdBLenGE(pClient, bufCmd, 1);
00363
00364 n = BSPROXY_CMD_HDR_LEN;
00365
00366 eDevType = bufCmd[n++];
00367
00368 switch( eDevType )
00369 {
00370 case BSPROXY_DEVTYPE_BPFOOT:
00371 case BSPROXY_DEVTYPE_BPIMU:
00372 case BSPROXY_DEVTYPE_BPHAND:
00373 case BSPROXY_DEVTYPE_BPCOMPASS:
00374 if( lenCmd <= n )
00375 {
00376 LOGERROR("%s: no I2C device address specified.",
00377 pClient->m_sClientName);
00378 return ClientSendFailRsp(pClient, bufCmd, "no parameter");
00379 }
00380 else if( (bufCmd[n] < 0x01) || (bufCmd[n] > 0x7f) )
00381 {
00382 LOGERROR("%s: 0x%x: I2C device address out of range.",
00383 pClient->m_sClientName, bufCmd[1]);
00384 return ClientSendFailRsp(pClient, bufCmd, "bad parameter");
00385 }
00386 i2cAddr = bufCmd[n++];
00387 break;
00388 case BSPROXY_DEVTYPE_I2C:
00389 case BSPROXY_DEVTYPE_RS232:
00390 case BSPROXY_DEVTYPE_RCB3:
00391 i2cAddr = 0;
00392 break;
00393 default:
00394 LOGERROR("%s: 0x%02x: unknown proxied device type.",
00395 pClient->m_sClientName, bufCmd[0]);
00396 return ClientSendFailRsp(pClient, bufCmd, "bad parameter");
00397 }
00398
00399 if( lenCmd <= n+1 )
00400 {
00401 LOGERROR("%s: no I2C device name specified.", pClient->m_sClientName);
00402 return ClientSendFailRsp(pClient, bufCmd, "no parameter");
00403 }
00404
00405 bufCmd[lenCmd-1] = 0;
00406 sDevName = (char *)&bufCmd[n];
00407
00408 if( (nHandle = ClientDevFindEmptySlot(pClient)) < 0 )
00409 {
00410 LOGERROR("%s: 0x%02x: cannot add device, currently at maximum %d",
00411 pClient->m_sClientName, bufCmd[1],
00412 BSPROXY_CLIENT_DEV_MAX);
00413 return ClientSendFailRsp(pClient, bufCmd, "too many devices");
00414 }
00415
00416 if( (pProxDev = ProxDevOpen(eDevType, sDevName)) == NULL )
00417 {
00418 LOGERROR("%s: %s: cannot open device", pClient->m_sClientName, sDevName);
00419 return ClientSendFailRsp(pClient, bufCmd, "cannot open device");
00420 }
00421
00422 pClient->m_tblClientDev[nHandle].m_eDevType = eDevType;
00423 pClient->m_tblClientDev[nHandle].m_pProxDev = pProxDev;
00424 pClient->m_tblClientDev[nHandle].m_i2cAddr = i2cAddr;
00425
00426 lenRsp = BSPROXY_RSP_HDR_LEN;
00427 bufRsp[lenRsp++] = (byte_t)nHandle;
00428
00429 LOGDIAG2("%s: created client handle=%d", pClient->m_sClientName, nHandle);
00430
00431 return ClientSendPassRsp(pClient, bufCmd, bufRsp, lenRsp);
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 static int CmdDevClose(BsProxyServer_T *pServer,
00455 BsProxyClient_T *pClient,
00456 byte_t bufCmd[], size_t lenCmd)
00457 {
00458 byte_t bufRsp[BSPROXY_MSG_MAX_LEN];
00459 size_t lenRsp;
00460 int nHandle;
00461
00462 BSPROXY_LOG_CMD(pClient, bufCmd, lenCmd);
00463
00464 if( (nHandle = ClientGetHandle(pClient, bufCmd)) < 0 )
00465 {
00466 return RC_ERROR;
00467 }
00468
00469 ProxDevClose(pClient->m_tblClientDev[nHandle].m_pProxDev);
00470
00471 pClient->m_tblClientDev[nHandle].m_eDevType = BSPROXY_DEVTYPE_NONE;
00472 pClient->m_tblClientDev[nHandle].m_pProxDev = NULL;
00473 pClient->m_tblClientDev[nHandle].m_i2cAddr = 0;
00474
00475 lenRsp = BSPROXY_RSP_HDR_LEN;
00476 bufRsp[lenRsp++] = (byte_t)nHandle;
00477
00478 LOGDIAG2("%s: deleted client handle=%d", pClient->m_sClientName, nHandle);
00479
00480 return ClientSendPassRsp(pClient, bufCmd, bufRsp, lenRsp);
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 static int CmdDevRead(BsProxyServer_T *pServer,
00506 BsProxyClient_T *pClient,
00507 byte_t bufCmd[], size_t lenCmd)
00508 {
00509 byte_t bufRsp[BSPROXY_MSG_MAX_LEN];
00510 size_t lenRsp;
00511 int nHandle;
00512 size_t n;
00513 BsProxyClientDev_T *pDev;
00514 byte_t i2cAddr = 0;
00515 size_t rlen;
00516 int nRead;
00517
00518 BSPROXY_LOG_CMD(pClient, bufCmd, lenCmd);
00519
00520 if( (nHandle = ClientGetHandle(pClient, bufCmd)) < 0 )
00521 {
00522 return RC_ERROR;
00523 }
00524
00525 pDev = &pClient->m_tblClientDev[nHandle];
00526
00527 n = BSPROXY_CMD_HDR_LEN+1;
00528
00529 switch( pDev->m_eDevType )
00530 {
00531 case BSPROXY_DEVTYPE_I2C:
00532 chkCmdBLenEQ(pClient, bufCmd, 3);
00533 i2cAddr = bufCmd[n++];
00534 rlen = (size_t)bufCmd[n++];
00535 break;
00536 case BSPROXY_DEVTYPE_BPFOOT:
00537 case BSPROXY_DEVTYPE_BPIMU:
00538 case BSPROXY_DEVTYPE_BPHAND:
00539 case BSPROXY_DEVTYPE_BPCOMPASS:
00540 chkCmdBLenEQ(pClient, bufCmd, 2);
00541 i2cAddr = pDev->m_i2cAddr;
00542 rlen = (size_t)bufCmd[n++];
00543 break;
00544 case BSPROXY_DEVTYPE_RCB3:
00545 chkCmdBLenEQ(pClient, bufCmd, 2);
00546 rlen = (size_t)bufCmd[n++];
00547 break;
00548 case BSPROXY_DEVTYPE_RS232:
00549 LOGERROR("%s: %s: read operation not implemented.",
00550 pClient->m_sClientName, pDev->m_pProxDev->m_sDevName);
00551 return ClientSendFailRsp(pClient, bufCmd, "operation not implemented");
00552 default:
00553 LOGERROR("%s: 0x%02x: unknown proxied device type.",
00554 pClient->m_sClientName, bufCmd[0]);
00555 return ClientSendFailRsp(pClient, bufCmd, "bad parameter");
00556 }
00557
00558 if(( rlen == 0) || (rlen > BSPROXY_RSP_BODY_LEN_MAX) )
00559 {
00560 LOGERROR("%s: %d: bad read length.", pClient->m_sClientName, rlen);
00561 return ClientSendFailRsp(pClient, bufCmd, "%d: bad read length.", rlen);
00562 }
00563
00564 switch( pDev->m_pProxDev->m_eDevClass )
00565 {
00566 case BSPROXY_DEVCLASS_I2C:
00567 nRead = ProxDevI2CRead(pDev->m_pProxDev, i2cAddr,
00568 &bufRsp[BSPROXY_RSP_HDR_LEN], rlen);
00569 break;
00570 case BSPROXY_DEVCLASS_RCB3:
00571 nRead = ProxDevRCB3Read(pDev->m_pProxDev,
00572 &bufRsp[BSPROXY_RSP_HDR_LEN], rlen);
00573 break;
00574 default:
00575 LOGERROR("%s: %s: read operation not implemented.",
00576 pClient->m_sClientName, pDev->m_pProxDev->m_sDevName);
00577 return ClientSendFailRsp(pClient, bufCmd, "operation not implemented");
00578 }
00579
00580 if( nRead <= 0 )
00581 {
00582 LOGERROR("%s: read operation failed.", pClient->m_sClientName);
00583 return ClientSendFailRsp(pClient, bufCmd, "read operation failed.");
00584 }
00585
00586 lenRsp = BSPROXY_RSP_HDR_LEN + nRead;
00587
00588 return ClientSendPassRsp(pClient, bufCmd, bufRsp, lenRsp);
00589 }
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 static int CmdDevWrite(BsProxyServer_T *pServer,
00614 BsProxyClient_T *pClient,
00615 byte_t bufCmd[], size_t lenCmd)
00616 {
00617 byte_t bufRsp[BSPROXY_MSG_MAX_LEN];
00618 size_t lenRsp;
00619 int nHandle;
00620 size_t n;
00621 BsProxyClientDev_T *pDev;
00622 byte_t i2cAddr = 0;
00623 size_t wlen;
00624 int nWritten;
00625
00626 BSPROXY_LOG_CMD(pClient, bufCmd, lenCmd);
00627
00628 if( (nHandle = ClientGetHandle(pClient, bufCmd)) < 0 )
00629 {
00630 return RC_ERROR;
00631 }
00632
00633 pDev = &pClient->m_tblClientDev[nHandle];
00634
00635 n = BSPROXY_CMD_HDR_LEN+1;
00636
00637 switch( pDev->m_eDevType )
00638 {
00639 case BSPROXY_DEVTYPE_I2C:
00640 chkCmdBLenGE(pClient, bufCmd, 3);
00641 i2cAddr = bufCmd[n++];
00642 break;
00643 case BSPROXY_DEVTYPE_BPFOOT:
00644 case BSPROXY_DEVTYPE_BPIMU:
00645 case BSPROXY_DEVTYPE_BPHAND:
00646 case BSPROXY_DEVTYPE_BPCOMPASS:
00647 chkCmdBLenGE(pClient, bufCmd, 2);
00648 i2cAddr = pDev->m_i2cAddr;
00649 break;
00650 case BSPROXY_DEVTYPE_RCB3:
00651 chkCmdBLenGE(pClient, bufCmd, 2);
00652 break;
00653 case BSPROXY_DEVTYPE_RS232:
00654 LOGERROR("%s: %s: read operation not implemented.",
00655 pClient->m_sClientName, pDev->m_pProxDev->m_sDevName);
00656 return ClientSendFailRsp(pClient, bufCmd, "operation not implemented");
00657 default:
00658 LOGERROR("%s: 0x%02x: unknown proxied device type.",
00659 pClient->m_sClientName, bufCmd[0]);
00660 return ClientSendFailRsp(pClient, bufCmd, "bad parameter");
00661 }
00662
00663 wlen = bufCmd[BSPROXY_CMD_HDR_BLEN_IDX] + BSPROXY_CMD_HDR_LEN - n;
00664
00665 if(( wlen == 0) || (wlen > BSPROXY_CMD_BODY_LEN_MAX) )
00666 {
00667 LOGERROR("%s: %d: bad write length.", pClient->m_sClientName, wlen);
00668 return ClientSendFailRsp(pClient, bufCmd, "%d: bad write length.", wlen);
00669 }
00670
00671 switch( pDev->m_pProxDev->m_eDevClass )
00672 {
00673 case BSPROXY_DEVCLASS_I2C:
00674 nWritten = ProxDevI2CWrite(pDev->m_pProxDev, i2cAddr, &bufCmd[n], wlen);
00675 break;
00676 case BSPROXY_DEVCLASS_RCB3:
00677 nWritten = ProxDevRCB3Write(pDev->m_pProxDev, &bufCmd[n], wlen);
00678 break;
00679 default:
00680 LOGERROR("%s: %s: read operation not implemented.",
00681 pClient->m_sClientName, pDev->m_pProxDev->m_sDevName);
00682 return ClientSendFailRsp(pClient, bufCmd, "operation not implemented");
00683 }
00684
00685 if( nWritten <= 0 )
00686 {
00687 LOGERROR("%s: write operation failed.", pClient->m_sClientName);
00688 return ClientSendFailRsp(pClient, bufCmd, "write operation failed.");
00689 }
00690
00691 lenRsp = BSPROXY_RSP_HDR_LEN;
00692 bufRsp[lenRsp++] = (byte_t)nWritten;
00693
00694 return ClientSendPassRsp(pClient, bufCmd, bufRsp, lenRsp);
00695 }
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 static int CmdDevTrans(BsProxyServer_T *pServer,
00721 BsProxyClient_T *pClient,
00722 byte_t bufCmd[], size_t lenCmd)
00723 {
00724 byte_t bufRsp[BSPROXY_MSG_MAX_LEN];
00725 size_t lenRsp;
00726 int nHandle;
00727 size_t n;
00728 BsProxyClientDev_T *pDev;
00729 byte_t i2cAddr = 0;
00730 size_t rlen;
00731 size_t wlen;
00732 int nRead;
00733
00734 BSPROXY_LOG_CMD(pClient, bufCmd, lenCmd);
00735
00736 if( (nHandle = ClientGetHandle(pClient, bufCmd)) < 0 )
00737 {
00738 return RC_ERROR;
00739 }
00740
00741 pDev = &pClient->m_tblClientDev[nHandle];
00742
00743 n = BSPROXY_CMD_HDR_LEN+1;
00744
00745 switch( pDev->m_eDevType )
00746 {
00747 case BSPROXY_DEVTYPE_I2C:
00748 chkCmdBLenGE(pClient, bufCmd, 4);
00749 i2cAddr = bufCmd[n++];
00750 rlen = bufCmd[n++];
00751 break;
00752 case BSPROXY_DEVTYPE_BPFOOT:
00753 case BSPROXY_DEVTYPE_BPIMU:
00754 case BSPROXY_DEVTYPE_BPHAND:
00755 case BSPROXY_DEVTYPE_BPCOMPASS:
00756 chkCmdBLenGE(pClient, bufCmd, 3);
00757 i2cAddr = pDev->m_i2cAddr;
00758 rlen = bufCmd[n++];
00759 break;
00760 case BSPROXY_DEVTYPE_RCB3:
00761 chkCmdBLenGE(pClient, bufCmd, 3);
00762 rlen = bufCmd[n++];
00763 break;
00764 case BSPROXY_DEVTYPE_RS232:
00765 LOGERROR("%s: %s: read operation not implemented.",
00766 pClient->m_sClientName, pDev->m_pProxDev->m_sDevName);
00767 return ClientSendFailRsp(pClient, bufCmd, "operation not implemented");
00768 default:
00769 LOGERROR("%s: 0x%02x: unknown proxied device type.",
00770 pClient->m_sClientName, bufCmd[0]);
00771 return ClientSendFailRsp(pClient, bufCmd, "bad parameter");
00772 }
00773
00774 if(( rlen == 0) || (rlen > BSPROXY_RSP_BODY_LEN_MAX) )
00775 {
00776 LOGERROR("%s: %d: bad read length.", pClient->m_sClientName, rlen);
00777 return ClientSendFailRsp(pClient, bufCmd, "%d: bad read length.", rlen);
00778 }
00779
00780 wlen = bufCmd[BSPROXY_CMD_HDR_BLEN_IDX] + BSPROXY_CMD_HDR_LEN - n;
00781
00782 if(( wlen == 0) || (wlen > BSPROXY_CMD_BODY_LEN_MAX) )
00783 {
00784 LOGERROR("%s: %d: bad write length.", pClient->m_sClientName, wlen);
00785 return ClientSendFailRsp(pClient, bufCmd, "%d: bad write length.", wlen);
00786 }
00787
00788 switch( pDev->m_pProxDev->m_eDevClass )
00789 {
00790 case BSPROXY_DEVCLASS_I2C:
00791 nRead = ProxDevI2CTrans(pDev->m_pProxDev, i2cAddr,
00792 &bufCmd[n], wlen, &bufRsp[BSPROXY_RSP_HDR_LEN], rlen);
00793 break;
00794 case BSPROXY_DEVCLASS_RCB3:
00795 nRead = ProxDevRCB3Trans(pDev->m_pProxDev,
00796 &bufCmd[n], wlen, &bufRsp[BSPROXY_RSP_HDR_LEN], rlen);
00797 break;
00798 default:
00799 LOGERROR("%s: %s: read operation not implemented.",
00800 pClient->m_sClientName, pDev->m_pProxDev->m_sDevName);
00801 return ClientSendFailRsp(pClient, bufCmd, "operation not implemented");
00802 }
00803
00804 if( nRead <= 0 )
00805 {
00806 LOGERROR("%s: transaction operation failed.", pClient->m_sClientName);
00807 return ClientSendFailRsp(pClient, bufCmd, "transaction operation failed.");
00808 }
00809
00810 lenRsp = BSPROXY_RSP_HDR_LEN + nRead;
00811
00812 return ClientSendPassRsp(pClient, bufCmd, bufRsp, lenRsp);
00813 }
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 static int CmdDevIoctl(BsProxyServer_T *pServer,
00841 BsProxyClient_T *pClient,
00842 byte_t bufCmd[], size_t lenCmd)
00843 {
00844 byte_t bufRsp[BSPROXY_MSG_MAX_LEN];
00845 size_t lenRsp;
00846 int nHandle;
00847 BsProxyClientDev_T *pDev;
00848 byte_t bufScan[128];
00849 int nScanned;
00850 int i;
00851
00852 BSPROXY_LOG_CMD(pClient, bufCmd, lenCmd);
00853
00854 if( (nHandle = ClientGetHandle(pClient, bufCmd)) < 0 )
00855 {
00856 return RC_ERROR;
00857 }
00858
00859 pDev = &pClient->m_tblClientDev[nHandle];
00860
00861 switch( pDev->m_pProxDev->m_eDevClass )
00862 {
00863 case BSPROXY_DEVTYPE_RS232:
00864 case BSPROXY_DEVTYPE_RCB3:
00865 LOGERROR("%s: %s: ioctl operation not implemented.",
00866 pClient->m_sClientName, pDev->m_pProxDev->m_sDevName);
00867 return ClientSendFailRsp(pClient, bufCmd, "operation not implemented");
00868 break;
00869 case BSPROXY_DEVTYPE_I2C:
00870 case BSPROXY_DEVTYPE_BPFOOT:
00871 case BSPROXY_DEVTYPE_BPIMU:
00872 case BSPROXY_DEVTYPE_BPHAND:
00873 case BSPROXY_DEVTYPE_BPCOMPASS:
00874 default:
00875 LOGERROR("%s: %s: scan operation not supported on device.",
00876 pClient->m_sClientName, pDev->m_pProxDev->m_sDevName);
00877 return ClientSendFailRsp(pClient, bufCmd, "operation not supported");
00878 }
00879
00880 lenRsp = BSPROXY_RSP_HDR_LEN;
00881 bufRsp[lenRsp++] = nScanned;
00882
00883 for(i=0; i<nScanned; ++i)
00884 {
00885 bufRsp[lenRsp++] = bufScan[i];
00886 }
00887
00888 LOGDIAG2("Found %d I2C devices", nScanned);
00889
00890 return ClientSendPassRsp(pClient, bufCmd, bufRsp, lenRsp);
00891 }
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916 static int CmdDevScan(BsProxyServer_T *pServer,
00917 BsProxyClient_T *pClient,
00918 byte_t bufCmd[], size_t lenCmd)
00919 {
00920 byte_t bufRsp[BSPROXY_MSG_MAX_LEN];
00921 size_t lenRsp;
00922 int nHandle;
00923 BsProxyClientDev_T *pDev;
00924 byte_t bufScan[128];
00925 int nScanned;
00926 int i;
00927
00928 BSPROXY_LOG_CMD(pClient, bufCmd, lenCmd);
00929
00930 if( (nHandle = ClientGetHandle(pClient, bufCmd)) < 0 )
00931 {
00932 return RC_ERROR;
00933 }
00934
00935 pDev = &pClient->m_tblClientDev[nHandle];
00936
00937 switch( pDev->m_pProxDev->m_eDevClass )
00938 {
00939 case BSPROXY_DEVCLASS_I2C:
00940 nScanned = ProxDevI2CScan(pDev->m_pProxDev, bufScan, sizeof(bufScan));
00941 break;
00942 default:
00943 LOGERROR("%s: %s: scan operation not supported on device.",
00944 pClient->m_sClientName, pDev->m_pProxDev->m_sDevName);
00945 return ClientSendFailRsp(pClient, bufCmd, "scan operation not supported");
00946 }
00947
00948 lenRsp = BSPROXY_RSP_HDR_LEN;
00949 bufRsp[lenRsp++] = nScanned;
00950
00951 for(i=0; i<nScanned; ++i)
00952 {
00953 bufRsp[lenRsp++] = bufScan[i];
00954 }
00955
00956 LOGDIAG2("Found %d I2C devices", nScanned);
00957
00958 return ClientSendPassRsp(pClient, bufCmd, bufRsp, lenRsp);
00959 }
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981 static int CmdDevCmd(BsProxyServer_T *pServer,
00982 BsProxyClient_T *pClient,
00983 byte_t bufCmd[], size_t lenCmd)
00984 {
00985 int nHandle;
00986 BsProxyClientDev_T *pDev;
00987
00988
00989
00990
00991 chkCmdBLenGE(pClient, bufCmd, 2);
00992
00993 if( (nHandle = ClientGetHandle(pClient, bufCmd)) < 0 )
00994 {
00995 return RC_ERROR;
00996 }
00997
00998 pDev = &pClient->m_tblClientDev[nHandle];
00999
01000
01001
01002
01003 switch( pDev->m_eDevType )
01004 {
01005
01006 case BSPROXY_DEVTYPE_BPFOOT:
01007 return BPFootDispatch(pServer, pClient, pDev, bufCmd, lenCmd);
01008
01009
01010 case BSPROXY_DEVTYPE_BPIMU:
01011 return BPIMUDispatch(pServer, pClient, pDev, bufCmd, lenCmd);
01012
01013
01014 case BSPROXY_DEVTYPE_RCB3:
01015 return RCB3Dispatch(pServer, pClient, pDev, bufCmd, lenCmd);
01016
01017 default:
01018 LOGERROR("%s: 0x%02x: no built-in specific commands are supported",
01019 pClient->m_sClientName, pDev->m_eDevType);
01020 return ClientSendFailRsp(pClient, bufCmd,
01021 "no commands for proxied device");
01022 }
01023 }
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048 int ClientDispatch(BsProxyServer_T *pServer,
01049 BsProxyClient_T *pClient,
01050 byte_t bufCmd[], size_t lenCmd)
01051 {
01052
01053
01054
01055 if( lenCmd < BSPROXY_CMD_HDR_LEN )
01056 {
01057 return ClientSendHdrError(pClient, bufCmd, lenCmd);
01058 }
01059
01060
01061
01062
01063
01064
01065
01066
01067 if( (size_t)bufCmd[BSPROXY_CMD_HDR_BLEN_IDX]+BSPROXY_CMD_HDR_LEN != lenCmd )
01068 {
01069 LOGERROR("%s: received %u bytes, but blen header field value is %u",
01070 pClient->m_sClientName, (uint_t)lenCmd,
01071 (uint_t)bufCmd[BSPROXY_CMD_HDR_BLEN_IDX]);
01072 return ClientSendFailRsp(pClient, bufCmd,
01073 "received %u bytes, but blen header field value is %u",
01074 (uint_t)lenCmd, (uint_t)bufCmd[BSPROXY_CMD_HDR_BLEN_IDX]);
01075 }
01076
01077
01078
01079
01080 switch( bufCmd[BSPROXY_CMD_HDR_MSGID_IDX] )
01081 {
01082
01083 case BSPROXY_MSGID_LOOPBACK:
01084 return CmdLoopback(pServer, pClient, bufCmd, lenCmd);
01085
01086
01087 case BSPROXY_MSGID_LOG:
01088 return CmdLog(pServer, pClient, bufCmd, lenCmd);
01089
01090
01091 case BSPROXY_MSGID_VERSION:
01092 return CmdVersion(pServer, pClient, bufCmd, lenCmd);
01093
01094
01095 case BSPROXY_MSGID_DEV_OPEN:
01096 return CmdDevOpen(pServer, pClient, bufCmd, lenCmd);
01097
01098
01099 case BSPROXY_MSGID_DEV_CLOSE:
01100 return CmdDevClose(pServer, pClient, bufCmd, lenCmd);
01101
01102
01103 case BSPROXY_MSGID_PROXY_INFO:
01104 return CmdProxyInfo(pServer, pClient, bufCmd, lenCmd);
01105
01106
01107 case BSPROXY_MSGID_DEV_READ:
01108 return CmdDevRead(pServer, pClient, bufCmd, lenCmd);
01109
01110
01111 case BSPROXY_MSGID_DEV_WRITE:
01112 return CmdDevWrite(pServer, pClient, bufCmd, lenCmd);
01113
01114
01115 case BSPROXY_MSGID_DEV_TRANS:
01116 return CmdDevTrans(pServer, pClient, bufCmd, lenCmd);
01117
01118
01119 case BSPROXY_MSGID_DEV_IOCTL:
01120 return CmdDevIoctl(pServer, pClient, bufCmd, lenCmd);
01121
01122
01123 case BSPROXY_MSGID_DEV_SCAN:
01124 return CmdDevScan(pServer, pClient, bufCmd, lenCmd);
01125
01126
01127 case BSPROXY_MSGID_DEV_CMD:
01128 return CmdDevCmd(pServer, pClient, bufCmd, lenCmd);
01129
01130 default:
01131 LOGERROR("%s: 0x%02x: unknown command",
01132 pClient->m_sClientName, bufCmd[BSPROXY_CMD_HDR_MSGID_IDX]);
01133 return RC_ERROR;
01134 }
01135
01136 LOGERROR("%s: here?", pClient->m_sClientName);
01137
01138 return RC_ERROR;
01139 }
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151 int ClientSendPassRsp(BsProxyClient_T *pClient, byte_t bufCmd[],
01152 byte_t bufRsp[], size_t lenRsp)
01153 {
01154 ssize_t n;
01155
01156
01157 bufRsp[BSPROXY_RSP_HDR_MSGID_IDX] = bufCmd[BSPROXY_CMD_HDR_MSGID_IDX];
01158 bufRsp[BSPROXY_RSP_HDR_TID_IDX] = bufCmd[BSPROXY_CMD_HDR_TID_IDX];
01159 bufRsp[BSPROXY_RSP_HDR_PF_IDX] = BSPROXY_RSP_PASS;
01160 bufRsp[BSPROXY_RSP_HDR_BLEN_IDX] = (byte_t)(lenRsp-BSPROXY_RSP_HDR_LEN);
01161
01162
01163 n = write(SocketAttrGetSd(pClient->m_pClientSock), bufRsp, lenRsp);
01164
01165 return n < (ssize_t)lenRsp? RC_ERROR: OK;
01166 }
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178 int ClientSendFailRsp(BsProxyClient_T *pClient, byte_t bufCmd[],
01179 const char *sErrFmt, ...)
01180 {
01181 byte_t bufRsp[BSPROXY_MSG_MAX_LEN];
01182 size_t lenBody, lenRsp;
01183 va_list ap;
01184 char *sBody;
01185
01186
01187 bufRsp[BSPROXY_RSP_HDR_MSGID_IDX] = bufCmd[BSPROXY_CMD_HDR_MSGID_IDX];
01188 bufRsp[BSPROXY_RSP_HDR_TID_IDX] = bufCmd[BSPROXY_CMD_HDR_TID_IDX];
01189 bufRsp[BSPROXY_RSP_HDR_PF_IDX] = BSPROXY_RSP_FAIL;
01190
01191 sBody = (char *)(bufRsp+BSPROXY_RSP_HDR_LEN);
01192
01193
01194
01195
01196 va_start(ap, sErrFmt);
01197
01198 vsnprintf(sBody, (size_t)(sizeof(bufRsp)-BSPROXY_RSP_HDR_LEN), sErrFmt, ap);
01199
01200 va_end(ap);
01201
01202
01203 bufRsp[sizeof(bufRsp)-1] = 0;
01204
01205 lenBody = strlen(sBody);
01206
01207
01208 sBody[lenBody++] = 0;
01209
01210
01211 bufRsp[BSPROXY_RSP_HDR_BLEN_IDX] = (byte_t)lenBody;
01212
01213
01214 lenRsp = BSPROXY_RSP_HDR_LEN + lenBody;
01215
01216
01217 write(SocketAttrGetSd(pClient->m_pClientSock), bufRsp, lenRsp);
01218
01219 return RC_ERROR;
01220 }
01221
01222
01223
01224
01225
01226
01227
01228
01229 BsProxyClient_T *ClientNew(Socket_T *pSockClient)
01230 {
01231 BsProxyClient_T *pClient;
01232 int i;
01233
01234 pClient = NEW(BsProxyClient_T);
01235 pClient->m_sClientName = SocketAttrGetRemoteName(pSockClient);
01236 pClient->m_pClientSock = pSockClient;
01237
01238 for(i=0; i<BSPROXY_CLIENT_DEV_MAX; ++i)
01239 {
01240 pClient->m_tblClientDev[i].m_eDevType = BSPROXY_DEVTYPE_NONE;
01241 pClient->m_tblClientDev[i].m_pProxDev = NULL;
01242 pClient->m_tblClientDev[i].m_i2cAddr = 0;
01243 }
01244
01245 return pClient;
01246 }
01247
01248
01249
01250
01251
01252
01253 void ClientDelete(BsProxyClient_T *pClient)
01254 {
01255 int i;
01256
01257 if( pClient == NULL )
01258 {
01259 return;
01260 }
01261
01262 for(i=0; i<BSPROXY_CLIENT_DEV_MAX; ++i)
01263 {
01264 if( pClient->m_tblClientDev[i].m_eDevType != BSPROXY_DEVTYPE_NONE )
01265 {
01266 ProxDevClose(pClient->m_tblClientDev[i].m_pProxDev);
01267 }
01268 }
01269
01270 SocketClose(pClient->m_pClientSock);
01271 SocketDelete(pClient->m_pClientSock);
01272
01273 delete(pClient);
01274 }