00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <OPENR/OPENRAPI.h>
00023 #include <OPENR/OPENRMessages.h>
00024 #include <iostream>
00025 #include <fstream>
00026 #include <map>
00027 #include <cstdlib>
00028 #include <cstring>
00029 #include <cctype>
00030 #include <pthread.h>
00031 #include <boot.h>
00032 #include <utils.h>
00033 #include <Platform.h>
00034 #include <Primitives.h>
00035 #include <MemoryMapAgent.h>
00036 #include <ModuleData.h>
00037 #include <opensdkAPI.h>
00038
00039 using namespace std;
00040
00041 #define LOCK(m) pthread_mutex_lock(&m ##_mutex)
00042 #define UNLOCK(m) pthread_mutex_unlock(&m ##_mutex)
00043
00044
00045 static longword myRobotStatus = orsbBATTERY_CONNECTED | orsbBATTERY_CAPACITY_FULL;
00046 static word myBatteryStatus = obsbFULLY_CHARGED;
00047 static word myRemainingCapacity = 100;
00048 static word myTemperature = 300;
00049 static word myFullyChargedCapacity = 55555;
00050 static word myVoltage = 5000;
00051 static word myCurrent = 1000;
00052 static OVolumeSwitch myVolume = ovolumeSW3;
00053 static OPower motorPower = opowerOFF;
00054 static word myBootCondition = 0;
00055
00056
00057 static map<OServiceEntry, OPowerStatus> powerStatusObservers;
00058 static pthread_mutex_t powerStatusObservers_mutex = PTHREAD_MUTEX_INITIALIZER;
00059
00060 #define sendPowerStatusNotifications(property, bitmask) \
00061 { \
00062 LOCK(powerStatusObservers); \
00063 \
00064 for(map<OServiceEntry, OPowerStatus>::iterator it = powerStatusObservers.begin(); it != powerStatusObservers.end(); ++it) { \
00065 if (it->second.property & bitmask) { \
00066 OPowerStatusMessage *status = new OPowerStatusMessage(myRobotStatus, myBatteryStatus, myRemainingCapacity, myTemperature, myFullyChargedCapacity, myVoltage, myCurrent, ::GetTimeDifference(), myVolume); \
00067 _sendMessage(it->first, status); \
00068 } \
00069 } \
00070 \
00071 UNLOCK(powerStatusObservers); \
00072 }
00073
00074
00075 OStatus OPENR::OpenPrimitive(const char* locator, OPrimitiveID* primitiveID)
00076 {
00077
00078 *primitiveID = oprimitiveID_UNDEF;
00079
00080 if (!locator) {
00081 return oINVALID_ARG;
00082 }
00083
00084
00085 int left = 0, right = num_of_primitives - 1;
00086
00087 do {
00088 unsigned int mid = (left + right) / 2;
00089 int cmp = strcmp(locator, primitives[mid].locator);
00090
00091 if (cmp < 0) {
00092 right = mid - 1;
00093 } else if (cmp > 0) {
00094 left = mid + 1;
00095 } else {
00096
00097 *primitiveID = mid;
00098 return oSUCCESS;
00099 }
00100 } while(left <= right);
00101
00102 return oNOT_FOUND;
00103 }
00104
00105 OStatus OPENR::ClosePrimitive(OPrimitiveID primitiveID)
00106 {
00107 CHECK_PRIMITIVEID()
00108
00109 return oSUCCESS;
00110 }
00111
00112 OStatus OPENR::ControlPrimitive(OPrimitiveID primitiveID, OPrimitiveRequest request, void* param, size_t paramSize, void* result, size_t resultSize)
00113 {
00114 CHECK_PRIMITIVEID()
00115
00116 switch (request) {
00117
00118
00119
00120 default:
00121 return oINVALID_ARG;
00122 }
00123 }
00124
00125 OStatus OPENR::NewCommandVectorData(size_t numCommands, MemoryRegionID* memID, OCommandVectorData** baseAddr)
00126 {
00127 const size_t size = sizeof(OCommandVectorData) + (sizeof(OCommandInfo) + sizeof(OCommandData))*numCommands;
00128 OCommandVectorData *data = *baseAddr = (OCommandVectorData*)malloc(size);
00129
00130 if (!data) {
00131 return oNO_MEMORY;
00132 }
00133
00134 data->vectorInfo.memRegionID = *memID = RegisterNewMemID(data);
00135 data->SetNumData(0);
00136 data->vectorInfo.offset = 0;
00137 data->vectorInfo.totalSize = size;
00138
00139 for (size_t i=0; i < numCommands; ++i) {
00140 OCommandInfo *info = data->GetInfo(i);
00141 info->dataOffset = sizeof(ODataVectorInfo) + sizeof(OCommandInfo)*numCommands + sizeof(OCommandData)*i;
00142 }
00143
00144 return oSUCCESS;
00145 }
00146
00147 OStatus OPENR::DeleteCommandVectorData(MemoryRegionID memID)
00148 {
00149 return FreeMemId(memID);
00150 }
00151
00152 OStatus OPENR::NewSoundVectorData(size_t numSounds, size_t dataSize, MemoryRegionID* memID, OSoundVectorData** baseAddr)
00153 {
00154 const size_t size = sizeof(OSoundVectorData) + (sizeof(OSoundInfo) + dataSize)*numSounds;
00155 OSoundVectorData *data = *baseAddr = (OSoundVectorData*)malloc(size);
00156
00157 if (!data) {
00158 return oNO_MEMORY;
00159 }
00160
00161 data->vectorInfo.memRegionID = *memID = RegisterNewMemID(data);
00162 data->SetNumData(0);
00163 data->vectorInfo.offset = 0;
00164 data->vectorInfo.totalSize = size;
00165
00166 for (size_t i=0; i < numSounds; ++i) {
00167 OSoundInfo *info = data->GetInfo(i);
00168 info->dataOffset = sizeof(ODataVectorInfo) + sizeof(OSoundInfo)*numSounds + dataSize*i;
00169 }
00170
00171 return oSUCCESS;
00172 }
00173
00174 OStatus OPENR::DeleteSoundVectorData(MemoryRegionID memID)
00175 {
00176 return FreeMemId(memID);
00177 }
00178
00179 OStatus OPENR::EnableJointGain(OPrimitiveID primitiveID)
00180 {
00181 CHECK_PRIMITIVEID_ALL()
00182
00183 return oSUCCESS;
00184 }
00185
00186 OStatus OPENR::DisableJointGain(OPrimitiveID primitiveID)
00187 {
00188 CHECK_PRIMITIVEID_ALL()
00189
00190 return oSUCCESS;
00191 }
00192
00193 OStatus OPENR::SetJointGain(OPrimitiveID primitiveID, word pg, word ig, word dg, word ps, word is, word ds)
00194 {
00195 CHECK_PRIMITIVEID_ALL()
00196
00197 return oSUCCESS;
00198 }
00199
00200 OStatus OPENR::RegisterDefaultJointGain(OPrimitiveID primitiveID, word pg, word ig, word dg, word ps, word is, word ds)
00201 {
00202 CHECK_PRIMITIVEID_ALL()
00203
00204 if (primitiveID == oprimitiveID_UNDEF) {
00205
00206 }
00207
00208 primitives[primitiveID].pg = pg;
00209 primitives[primitiveID].ig = ig;
00210 primitives[primitiveID].dg = dg;
00211 primitives[primitiveID].ps = ps;
00212 primitives[primitiveID].is = is;
00213 primitives[primitiveID].ds = ds;
00214
00215 return oSUCCESS;
00216 }
00217
00218 OStatus OPENR::GetJointGain(OPrimitiveID primitiveID, word* pg, word* ig, word* dg, word* ps, word* is, word* ds)
00219 {
00220 CHECK_PRIMITIVEID()
00221
00222 return oFAIL;
00223 }
00224
00225 OStatus OPENR::GetDefaultJointGain(OPrimitiveID primitiveID, word* pg, word* ig, word* dg, word* ps, word* is, word* ds)
00226 {
00227 if (primitiveID >= num_of_primitives || primitiveID < 0) {
00228 *pg = *ig = *dg = *ps = *is = *ds = 0;
00229 return oFAIL;
00230 }
00231
00232 *pg = primitives[primitiveID].pg;
00233 *ig = primitives[primitiveID].ig;
00234 *dg = primitives[primitiveID].dg;
00235 *ps = primitives[primitiveID].ps;
00236 *is = primitives[primitiveID].is;
00237 *ds = primitives[primitiveID].ds;
00238
00239 return oSUCCESS;
00240 }
00241
00242 OStatus OPENR::SetDefaultJointGain(OPrimitiveID primitiveID)
00243 {
00244 CHECK_PRIMITIVEID_ALL()
00245
00246 return oFAIL;
00247 }
00248
00249 OStatus OPENR::GetJointValue(OPrimitiveID primitiveID, OJointValue* value)
00250 {
00251 CHECK_PRIMITIVEID()
00252 return ::GetJointValue(primitiveID, value);
00253 }
00254
00255 OStatus OPENR::GetSensorValue(OPrimitiveID primitiveID, OSensorValue* value)
00256 {
00257 CHECK_PRIMITIVEID()
00258 return ::GetSensorValue(primitiveID, value);
00259 }
00260
00261 OStatus OPENR::NewSyncKey(OVRSyncKey* key)
00262 {
00263
00264 return oFAIL;
00265 }
00266
00267 OStatus OPENR::CancelSyncKey(OVRSyncKey key)
00268 {
00269
00270 return oFAIL;
00271 }
00272
00273 OStatus OPENR::DivideSyncKey(OVRSyncKey key, OVRSyncKey* key1, OVRSyncKey* key2)
00274 {
00275
00276 return oFAIL;
00277 }
00278
00279 OStatus OPENR::NewCdtVectorData(MemoryRegionID* memID, OCdtVectorData** baseAddr)
00280 {
00281 OCdtVectorData *data = *baseAddr = (OCdtVectorData*)malloc(sizeof(OCdtVectorData));
00282 data->vectorInfo.memRegionID = *memID = RegisterNewMemID(data);
00283 data->SetNumData(0);
00284 data->vectorInfo.offset = 0;
00285 data->vectorInfo.totalSize = sizeof(OCdtVectorData);
00286
00287 return oSUCCESS;
00288 }
00289
00290 OStatus OPENR::DeleteCdtVectorData(MemoryRegionID memID)
00291 {
00292 return FreeMemId(memID);
00293 }
00294
00295 OStatus OPENR::SetCdtVectorData(MemoryRegionID memID)
00296 {
00297
00298 return oFAIL;
00299 }
00300
00301 OStatus OPENR::SetMotorPower(OPower power)
00302 {
00303 bool changed = false;
00304 motorPower = power;
00305
00306 if (power) {
00307 if (!(power & orsbMOTOR_POWER)) {
00308 myRobotStatus |= orsbMOTOR_POWER;
00309 changed = true;
00310 }
00311 } else {
00312 if (power & orsbMOTOR_POWER) {
00313 myRobotStatus &= ~orsbMOTOR_POWER;
00314 changed = true;
00315 }
00316 }
00317
00318 if (changed) {
00319 sendPowerStatusNotifications(robotStatus, orsbMOTOR_POWER);
00320 }
00321
00322 return oSUCCESS;
00323 }
00324
00325 OStatus OPENR::Shutdown(const OBootCondition& bootCondition)
00326 {
00327
00328 if (bootCondition.bitmap & obcbPAUSE_SW) {
00329 myBootCondition |= obcbPAUSE_SW;
00330 myRobotStatus |= orsbPAUSE;
00331
00332 sendPowerStatusNotifications(robotStatus, orsbPAUSE);
00333 shutdown();
00334 return oSUCCESS;
00335 }
00336
00337
00338
00339
00340
00341 return oFAIL;
00342 }
00343
00344 OStatus OPENR::GetBootCondition(OBootCondition* bootCondition)
00345 {
00346 bootCondition->bitmap = myBootCondition;
00347 return oSUCCESS;
00348 }
00349
00350 OStatus OPENR::GetPowerStatus(OPowerStatus* powerStatus)
00351 {
00352 powerStatus->robotStatus = myRobotStatus;
00353 powerStatus->batteryStatus = myBatteryStatus;
00354 powerStatus->remainingCapacity = myRemainingCapacity;
00355 powerStatus->temperature = myTemperature;
00356 powerStatus->fullyChargedCapacity = myFullyChargedCapacity;
00357 powerStatus->voltage = myVoltage;
00358 powerStatus->current = myCurrent;
00359 powerStatus->timeDif = ::GetTimeDifference();
00360 powerStatus->volume = myVolume;
00361 return oSUCCESS;
00362 }
00363
00364 OStatus OPENR::ObservePowerStatus(const OPowerStatus& notifyStatus, const OServiceEntry& entry)
00365 {
00366 LOCK(powerStatusObservers);
00367 powerStatusObservers[entry] = notifyStatus;
00368 UNLOCK(powerStatusObservers);
00369
00370 return oSUCCESS;
00371 }
00372
00373 OStatus OPENR::UnobservePowerStatus(const OServiceEntry& entry)
00374 {
00375 OStatus retval = oINVALID_ARG;
00376
00377 LOCK(powerStatusObservers);
00378
00379 map<OServiceEntry, OPowerStatus>::iterator it = powerStatusObservers.find(entry);
00380 if (it != powerStatusObservers.end()) {
00381 powerStatusObservers.erase(it);
00382 retval = oSUCCESS;
00383 }
00384
00385 UNLOCK(powerStatusObservers);
00386
00387 return retval;
00388 }
00389
00390 OStatus OPENR::FindDesignData(const char* keyword, ODesignDataID* dataID, byte** data, size_t* size)
00391 {
00392 if (!strcmp(keyword, odesignkeywordCPUINFO)) {
00393
00394 return oFAIL;
00395 }
00396
00397 char *path = resolve_case_insensitive_path("MS/OPEN-R/MW/CONF/DESIGNDB.CFG");
00398 fstream DB(path);
00399 free(path);
00400
00401 if (!DB) {
00402 return oFAIL;
00403 }
00404
00405
00406 string line;
00407 bool mySection = true;
00408
00409 const size_t keyword_len = strlen(keyword);
00410
00411 while(getNonEmptyLine(DB, line, true, &mySection)) {
00412 if (!strncmp(keyword, line.c_str(), keyword_len) && isspace(line[keyword_len])) {
00413 char *name = (char*)line.c_str() + keyword_len + 1;
00414
00415 while (isspace(*name)) ++name;
00416 ++name;
00417
00418 *data = (byte*)file_get_contents(name, size);
00419 if (!*data) {
00420 return (size == 0 ? oDESIGNDATA_SIZE_ZERO : oNOT_FOUND);
00421 }
00422
00423
00424 *dataID = MOD_DATA(lastDesignDataID)++;
00425 DesignData tmp = {*data, *size};
00426 MOD_DATA(designDataIDs)[*dataID] = tmp;
00427
00428 return oSUCCESS;
00429 }
00430 }
00431 return oNOT_FOUND;
00432 }
00433
00434 OStatus OPENR::DeleteDesignData(ODesignDataID dataID)
00435 {
00436 map<ODesignDataID, DesignData>::iterator it = MOD_DATA(designDataIDs).find(dataID);
00437
00438
00439 if (it == MOD_DATA(designDataIDs).end()) {
00440 return oINVALID_ARG;
00441 }
00442
00443 DesignData data = it->second;
00444
00445 if (!file_unmap_contents(data.base, data.size)) {
00446 return oFAIL;
00447 }
00448
00449 MOD_DATA(designDataIDs).erase(it);
00450 return oSUCCESS;
00451 }
00452
00453 OStatus OPENR::GetRobotDesign(char* robotDesign)
00454 {
00455 strcpy(robotDesign, ROBOTDESIGN);
00456 return oSUCCESS;
00457 }
00458
00459 OStatus OPENR::GetMemoryStickStatus(OMemoryStickStatus* status)
00460 {
00461
00462 return oFAIL;
00463 }
00464
00465 OStatus OPENR::Fatal(OFatal fatal)
00466 {
00467
00468 return oFAIL;
00469 }
00470
00471 OStatus OPENR::SetTime(const OTime& time)
00472 {
00473 return ::SetTime(time);
00474 }
00475
00476 OStatus OPENR::GetTime(OTime* time_)
00477 {
00478 time_->Set(::getSystemTime().seconds, 0);
00479 return oSUCCESS;
00480 }
00481
00482 OStatus OPENR::SetTimeDifference(sbyte timeDifference)
00483 {
00484 if (::SetTimeDifference(timeDifference) == oSUCCESS) {
00485 sendPowerStatusNotifications(timeDif, opsoTIME_DIF_NOTIFY_EVERY_CHANGE);
00486 return oSUCCESS;
00487 }
00488
00489 return oFAIL;
00490 }
00491
00492 OStatus OPENR::GetTimeDifference(sbyte* timeDifference)
00493 {
00494 *timeDifference = ::GetTimeDifference();
00495 return oSUCCESS;
00496 }
00497
00498 OStatus OPENR::SetVolumeSwitch(OVolumeSwitch volSW)
00499 {
00500
00501
00502 if (volSW != ovolumeSW0 && volSW != ovolumeSW1 && volSW != ovolumeSW2 && volSW != ovolumeSW3) {
00503 return oFAIL;
00504 }
00505
00506 if (myVolume != volSW) {
00507 myVolume = volSW;
00508 sendPowerStatusNotifications(volume, opsoVOLUME_NOTIFY_EVERY_CHANGE);
00509 }
00510 return oSUCCESS;
00511 }
00512
00513 OStatus OPENR::GetVolumeSwitch(OVolumeSwitch* volSW)
00514 {
00515 *volSW = myVolume;
00516 return oSUCCESS;
00517 }