objacces.c

Go to the documentation of this file.
00001 /*
00002   This file is part of CanFestival, a library implementing CanOpen
00003   Stack.
00004 
00005   Copyright (C): Edouard TISSERANT and Francis DUPIN
00006 
00007   See COPYING file for copyrights details.
00008 
00009   This library is free software; you can redistribute it and/or
00010   modify it under the terms of the GNU Lesser General Public
00011   License as published by the Free Software Foundation; either
00012   version 2.1 of the License, or (at your option) any later version.
00013 
00014   This library is distributed in the hope that it will be useful,
00015   but WITHOUT ANY WARRANTY; without even the implied warranty of
00016   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017   Lesser General Public License for more details.
00018 
00019   You should have received a copy of the GNU Lesser General Public
00020   License along with this library; if not, write to the Free Software
00021   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00022   USA
00023 */
00037 /* #define DEBUG_WAR_CONSOLE_ON */
00038 /* #define DEBUG_ERR_CONSOLE_ON */
00039 
00040 
00041 #include "objacces.h"
00042 
00043 
00055 UNS8 accessDictionaryError(UNS16 index, UNS8 subIndex,
00056                            UNS8 sizeDataDict, UNS8 sizeDataGiven, UNS32 code)
00057 {
00058 #ifdef DEBUG_WAR_CONSOLE_ON
00059   MSG_WAR(0x2B09,"Dictionary index : ", index);
00060   MSG_WAR(0X2B10,"           subindex : ", subIndex);
00061   switch (code) {
00062   case  OD_NO_SUCH_OBJECT:
00063     MSG_WAR(0x2B11,"Index not found ", index);
00064     break;
00065   case OD_NO_SUCH_SUBINDEX :
00066     MSG_WAR(0x2B12,"SubIndex not found ", subIndex);
00067     break;
00068   case OD_WRITE_NOT_ALLOWED :
00069     MSG_WAR(0x2B13,"Write not allowed, data is read only ", index);
00070     break;
00071   case OD_LENGTH_DATA_INVALID :
00072     MSG_WAR(0x2B14,"Conflict size data. Should be (bytes)  : ", sizeDataDict);
00073     MSG_WAR(0x2B15,"But you have given the size  : ", sizeDataGiven);
00074     break;
00075   case OD_NOT_MAPPABLE :
00076     MSG_WAR(0x2B16,"Not mappable data in a PDO at index    : ", index);
00077     break;
00078   case OD_VALUE_TOO_LOW :
00079     MSG_WAR(0x2B17,"Value range error : value too low. SDOabort : ", code);
00080     break;
00081   case OD_VALUE_TOO_HIGH :
00082     MSG_WAR(0x2B18,"Value range error : value too high. SDOabort : ", code);
00083     break;
00084   default :
00085     MSG_WAR(0x2B20, "Unknown error code : ", code);
00086   }
00087 #endif
00088   return 0;
00089 }
00090 
00105 UNS32 _getODentry( CO_Data* d,
00106                    UNS16 wIndex,
00107                    UNS8 bSubindex,
00108                    void * pDestData,
00109                    UNS8 * pExpectedSize,
00110                    UNS8 * pDataType,
00111                    UNS8 checkAccess,
00112                    UNS8 endianize)
00113 { /* DO NOT USE MSG_ERR because the macro may send a PDO -> infinite
00114     loop if it fails. */
00115   UNS32 errorCode;
00116   UNS8 szData;
00117   const indextable *ptrTable;
00118   ODCallback_t *Callback;
00119 
00120   ptrTable = (*d->scanIndexOD)(wIndex, &errorCode, &Callback);
00121 
00122   if (errorCode != OD_SUCCESSFUL)
00123     return errorCode;
00124   if( ptrTable->bSubCount <= bSubindex ) {
00125     /* Subindex not found */
00126     accessDictionaryError(wIndex, bSubindex, 0, 0, OD_NO_SUCH_SUBINDEX);
00127     return OD_NO_SUCH_SUBINDEX;
00128   }
00129 
00130   if (checkAccess && !(ptrTable->pSubindex[bSubindex].bAccessType & WO)) {
00131     MSG_WAR(0x2B30, "Access Type : ", ptrTable->pSubindex[bSubindex].bAccessType);
00132     accessDictionaryError(wIndex, bSubindex, 0, 0, OD_WRITE_NOT_ALLOWED);
00133     return OD_READ_NOT_ALLOWED;
00134   }
00135 
00136   *pDataType = ptrTable->pSubindex[bSubindex].bDataType;
00137   szData = ptrTable->pSubindex[bSubindex].size;
00138 
00139   if(*pExpectedSize == 0 ||
00140      *pExpectedSize == szData ||
00141      (*pDataType == visible_string && *pExpectedSize < szData)) {
00142     /* We
00143       allow to fetch a shorter string than expected */
00144 
00145 #  ifdef CANOPEN_BIG_ENDIAN
00146     if(endianize && *pDataType > boolean && *pDataType < visible_string) {
00147       /* data must be transmited with low byte first */
00148       UNS8 i, j = 0;
00149       MSG_WAR(boolean, "data type ", *pDataType);
00150       MSG_WAR(visible_string, "data type ", *pDataType);
00151       for ( i = szData ; i > 0 ; i--) {
00152         MSG_WAR(i," ", j);
00153         ((UNS8*)pDestData)[j++] =
00154           ((UNS8*)ptrTable->pSubindex[bSubindex].pObject)[i-1];
00155       }
00156     }
00157     else /* It it is a visible string no endianisation to perform */
00158       memcpy(pDestData, ptrTable->pSubindex[bSubindex].pObject,szData);
00159 #  else
00160     memcpy(pDestData, ptrTable->pSubindex[bSubindex].pObject,szData);
00161 #  endif
00162 
00163     *pExpectedSize = szData;
00164 #if 0
00165     /* Me laisser a, please ! (FD) */
00166     {
00167       UNS8 i;
00168       for (i = 0 ; i < 10 ; i++) {
00169         MSG_WAR(*pExpectedSize, "dic data= ",
00170                 *(UNS8 *)(ptrTable->pSubindex[bSubindex].pObject + i));
00171       }
00172 
00173     }
00174 #endif
00175     return OD_SUCCESSFUL;
00176   }
00177   else { /* Error ! */
00178     *pExpectedSize = szData;
00179     accessDictionaryError(wIndex, bSubindex, szData,
00180                           *pExpectedSize, OD_LENGTH_DATA_INVALID);
00181     return OD_LENGTH_DATA_INVALID;
00182   }
00183 }
00184 
00198 UNS32 getODentry( CO_Data* d,
00199                   UNS16 wIndex,
00200                   UNS8 bSubindex,
00201                   void * pDestData,
00202                   UNS8 * pExpectedSize,
00203                   UNS8 * pDataType,
00204                   UNS8 checkAccess)
00205 {
00206   return _getODentry( d,
00207                       wIndex,
00208                       bSubindex,
00209                       pDestData,
00210                       pExpectedSize,
00211                       pDataType,
00212                       checkAccess,
00213                       1);//endianize
00214 }
00215 
00229 UNS32 readLocalDict( CO_Data* d,
00230                      UNS16 wIndex,
00231                      UNS8 bSubindex,
00232                      void * pDestData,
00233                      UNS8 * pExpectedSize,
00234                      UNS8 * pDataType,
00235                      UNS8 checkAccess)
00236 {
00237   return _getODentry( d,
00238                       wIndex,
00239                       bSubindex,
00240                       pDestData,
00241                       pExpectedSize,
00242                       pDataType,
00243                       checkAccess,
00244                       0);//do not endianize
00245 }
00246 
00260 UNS32 _setODentry( CO_Data* d,
00261                    UNS16 wIndex,
00262                    UNS8 bSubindex,
00263                    void * pSourceData,
00264                    UNS8 * pExpectedSize,
00265                    UNS8 checkAccess,
00266                    UNS8 endianize)
00267 {
00268   UNS8 szData;
00269   UNS8 dataType;
00270   UNS32 errorCode;
00271   const indextable *ptrTable;
00272   ODCallback_t *Callback;
00273 
00274   ptrTable =(*d->scanIndexOD)(wIndex, &errorCode, &Callback);
00275   if (errorCode != OD_SUCCESSFUL)
00276     return errorCode;
00277 
00278   if( ptrTable->bSubCount <= bSubindex ) {
00279     /* Subindex not found */
00280     accessDictionaryError(wIndex, bSubindex, 0, *pExpectedSize, OD_NO_SUCH_SUBINDEX);
00281     return OD_NO_SUCH_SUBINDEX;
00282   }
00283   if (checkAccess && (ptrTable->pSubindex[bSubindex].bAccessType == RO)) {
00284     MSG_WAR(0x2B25, "Access Type : ", ptrTable->pSubindex[bSubindex].bAccessType);
00285     accessDictionaryError(wIndex, bSubindex, 0, *pExpectedSize, OD_WRITE_NOT_ALLOWED);
00286     return OD_WRITE_NOT_ALLOWED;
00287   }
00288 
00289 
00290   dataType = ptrTable->pSubindex[bSubindex].bDataType;
00291   szData = ptrTable->pSubindex[bSubindex].size;
00292 
00293   if( *pExpectedSize == 0 ||
00294       *pExpectedSize == szData ||
00295       (dataType == visible_string && *pExpectedSize < szData)) /* We
00296                                                                   allow to store a shorter string than entry size */
00297     {
00298 #ifdef CANOPEN_BIG_ENDIAN
00299       if(endianize && dataType > boolean && dataType < visible_string)
00300         {
00301           /* we invert the data source directly. This let us do range
00302             testing without */
00303           /* additional temp variable */
00304           UNS8 i;
00305           for ( i = 0 ; i < ( ptrTable->pSubindex[bSubindex].size >> 1)  ; i++)
00306             {
00307               UNS8 tmp =((UNS8 *)pSourceData) [(ptrTable->pSubindex[bSubindex].size - 1) - i];
00308               ((UNS8 *)pSourceData) [(ptrTable->pSubindex[bSubindex].size - 1) - i] = ((UNS8 *)pSourceData)[i];
00309               ((UNS8 *)pSourceData)[i] = tmp;
00310             }
00311         }
00312 #endif
00313       errorCode = (*d->valueRangeTest)(dataType, pSourceData);
00314       if (errorCode) {
00315         accessDictionaryError(wIndex, bSubindex, szData, *pExpectedSize, errorCode);
00316         return errorCode;
00317       }
00318       memcpy(ptrTable->pSubindex[bSubindex].pObject,pSourceData, *pExpectedSize);
00319       *pExpectedSize = szData;
00320 
00321       /* Callbacks */
00322       if(Callback && Callback[bSubindex]){
00323         (*Callback[bSubindex])(d, ptrTable, bSubindex);
00324       }
00325 
00326       /* TODO : Store dans NVRAM */
00327       if (ptrTable->pSubindex[bSubindex].bAccessType & TO_BE_SAVE){
00328         (*d->storeODSubIndex)(wIndex, bSubindex);
00329       }
00330       return OD_SUCCESSFUL;
00331     }else{
00332       *pExpectedSize = szData;
00333       accessDictionaryError(wIndex, bSubindex, szData, *pExpectedSize, OD_LENGTH_DATA_INVALID);
00334       return OD_LENGTH_DATA_INVALID;
00335     }
00336 }
00337 
00350 UNS32 setODentry( CO_Data* d,
00351                   UNS16 wIndex,
00352                   UNS8 bSubindex,
00353                   void * pSourceData,
00354                   UNS8 * pExpectedSize,
00355                   UNS8 checkAccess)
00356 {
00357   return _setODentry( d,
00358                       wIndex,
00359                       bSubindex,
00360                       pSourceData,
00361                       pExpectedSize,
00362                       checkAccess,
00363                       1);//endianize
00364 }
00365 
00378 UNS32 writeLocalDict( CO_Data* d,
00379                       UNS16 wIndex,
00380                       UNS8 bSubindex,
00381                       void * pSourceData,
00382                       UNS8 * pExpectedSize,
00383                       UNS8 checkAccess)
00384 {
00385   return _setODentry( d,
00386                       wIndex,
00387                       bSubindex,
00388                       pSourceData,
00389                       pExpectedSize,
00390                       checkAccess,
00391                       0);//do not endianize
00392 }
00393 
00404 const indextable * scanIndexOD (CO_Data* d, UNS16 wIndex, UNS32 *errorCode, ODCallback_t **Callback)
00405 {
00406   return (*d->scanIndexOD)(wIndex, errorCode, Callback);
00407 }
00408 
00419 UNS32 RegisterSetODentryCallBack(CO_Data* d, UNS16 wIndex, UNS8 bSubindex, ODCallback_t Callback)
00420 {
00421   UNS32 errorCode;
00422   ODCallback_t *CallbackList;
00423 
00424   scanIndexOD (d, wIndex, &errorCode, &CallbackList);
00425   if(errorCode == OD_SUCCESSFUL && CallbackList)
00426     CallbackList[bSubindex] = Callback;
00427   return errorCode;
00428 }
00429 
00436 void _storeODSubIndex (UNS16 wIndex, UNS8 bSubindex){}

Generated on Mon Jul 2 19:10:16 2007 for CanFestival by  doxygen 1.5.1