00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "r_servicebook.h"
00024 #include "record-internal.h"
00025 #include "protocol.h"
00026 #include "protostructs.h"
00027 #include "data.h"
00028 #include "time.h"
00029 #include "error.h"
00030 #include "endian.h"
00031 #include <ostream>
00032 #include <iomanip>
00033 #include <time.h>
00034 #include <stdexcept>
00035
00036 #define __DEBUG_MODE__
00037 #include "debug.h"
00038
00039 using namespace std;
00040 using namespace Barry::Protocol;
00041
00042 namespace Barry {
00043
00044
00045
00046
00047
00048
00049 #define SBFCC_END 0xffff
00050
00051 FieldLink<ServiceBookConfig> ServiceBookConfigFieldLinks[] = {
00052
00053 { SBFCC_END, "End of List",0, 0, 0, 0, 0 }
00054 };
00055
00056 ServiceBookConfig::ServiceBookConfig()
00057 : Format(0)
00058 {
00059 Clear();
00060 }
00061
00062 ServiceBookConfig::~ServiceBookConfig()
00063 {
00064 }
00065
00066 const unsigned char* ServiceBookConfig::ParseField(const unsigned char *begin,
00067 const unsigned char *end)
00068 {
00069 const void *raw;
00070 uint16_t size, type;
00071
00072 switch( Format )
00073 {
00074 case 0x02:
00075 {
00076 const PackedField_02 *field = (const PackedField_02 *) begin;
00077 raw = field->raw;
00078 size = field->size;
00079 type = field->type;
00080 begin += PACKED_FIELD_02_HEADER_SIZE + size;
00081 }
00082 break;
00083
00084 case 0x10:
00085 {
00086 const PackedField_10 *field = (const PackedField_10 *) begin;
00087 raw = field->raw;
00088 size = field->size;
00089 type = field->type;
00090 begin += PACKED_FIELD_10_HEADER_SIZE + size;
00091 }
00092 break;
00093
00094 default:
00095 eout("Unknown packed field format" << Format);
00096 return begin + 1;
00097 }
00098
00099
00100
00101 if( begin > end )
00102 return begin;
00103
00104 if( !size )
00105 return begin;
00106
00107
00108 for( FieldLink<ServiceBookConfig> *b = ServiceBookConfigFieldLinks;
00109 b->type != SBFCC_END;
00110 b++ )
00111 {
00112 if( b->type == type ) {
00113 if( b->strMember ) {
00114 std::string &s = this->*(b->strMember);
00115 s = ParseFieldString(raw, size-1);
00116 return begin;
00117 }
00118 }
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 UnknownField uf;
00130 uf.type = type;
00131 uf.data.assign((const char*)raw, size);
00132 Unknowns.push_back(uf);
00133
00134
00135 return begin;
00136 }
00137
00138 void ServiceBookConfig::ParseHeader(const Data &data, size_t &offset)
00139 {
00140 MAKE_RECORD(const Barry::Protocol::ServiceBookConfigField, sbc, data, offset);
00141 offset += SERVICE_BOOK_CONFIG_FIELD_HEADER_SIZE;
00142 if( data.GetSize() >= offset ) {
00143 Format = sbc->format;
00144 }
00145 }
00146
00147 void ServiceBookConfig::ParseFields(const Data &data, size_t &offset)
00148 {
00149 const unsigned char *finish = ParseCommonFields(*this,
00150 data.GetData() + offset, data.GetData() + data.GetSize());
00151 offset += finish - (data.GetData() + offset);
00152 }
00153
00154 void ServiceBookConfig::BuildHeader(Data &data, size_t &offset) const
00155 {
00156
00157 data.GetBuffer(offset + SERVICE_BOOK_CONFIG_FIELD_HEADER_SIZE);
00158
00159 MAKE_RECORD(Barry::Protocol::ServiceBookConfigField, sbc, data, offset);
00160 sbc->format = Format;
00161
00162 offset += SERVICE_BOOK_CONFIG_FIELD_HEADER_SIZE;
00163 }
00164
00165
00166
00167
00168
00169
00170 void ServiceBookConfig::BuildFields(Data &data, size_t &offset) const
00171 {
00172 throw std::logic_error("ServiceBookConfig::Build not yet implemented");
00173 }
00174
00175 void ServiceBookConfig::Clear()
00176 {
00177 Unknowns.clear();
00178 }
00179
00180 void ServiceBookConfig::Dump(std::ostream &os) const
00181 {
00182 os << " ServiceBookConfig Format: " << setbase(16) << (uint16_t)Format << "\n";
00183
00184
00185 for( const FieldLink<ServiceBookConfig> *b = ServiceBookConfigFieldLinks;
00186 b->type != SBFCC_END;
00187 b++ )
00188 {
00189 if( b->strMember ) {
00190 const std::string &s = this->*(b->strMember);
00191 if( s.size() )
00192 os << " " << b->name << ": " << s << "\n";
00193 }
00194 else if( b->timeMember ) {
00195 time_t t = this->*(b->timeMember);
00196 if( t > 0 )
00197 os << " " << b->name << ": " << ctime(&t);
00198 }
00199 }
00200
00201
00202 os << Unknowns;
00203 os << " ------------------- End of Config Field\n";
00204 }
00205
00206
00207
00208
00209
00210
00211 #define SBFC_OLD_NAME 0x01
00212 #define SBFC_HIDDEN_NAME 0x02
00213 #define SBFC_NAME 0x03
00214 #define SBFC_OLD_UNIQUE_ID 0x06
00215 #define SBFC_UNIQUE_ID 0x07
00216 #define SBFC_CONTENT_ID 0x08
00217 #define SBFC_CONFIG 0x09
00218 #define SBFC_OLD_DESC 0x32
00219 #define SBFC_DESCRIPTION 0x0f
00220 #define SBFC_DSID 0xa1
00221 #define SBFC_BES_DOMAIN 0xa2
00222 #define SBFC_USER_ID 0xa3
00223 #define SBFC_END 0xffff
00224
00225 FieldLink<ServiceBook> ServiceBookFieldLinks[] = {
00226 { SBFC_HIDDEN_NAME, "Hidden Name",0, 0, &ServiceBook::HiddenName, 0, 0 },
00227 { SBFC_DSID, "DSID", 0, 0, &ServiceBook::DSID, 0, 0 },
00228 { SBFC_END, "End of List",0, 0, 0, 0, 0 }
00229 };
00230
00231 ServiceBook::ServiceBook()
00232 : NameType(SBFC_OLD_NAME),
00233 DescType(SBFC_OLD_DESC),
00234 UniqueIdType(SBFC_OLD_UNIQUE_ID),
00235 RecordId(0)
00236 {
00237 Clear();
00238 }
00239
00240 ServiceBook::~ServiceBook()
00241 {
00242 }
00243
00244 const unsigned char* ServiceBook::ParseField(const unsigned char *begin,
00245 const unsigned char *end)
00246 {
00247 const CommonField *field = (const CommonField *) begin;
00248
00249
00250 begin += COMMON_FIELD_HEADER_SIZE + btohs(field->size);
00251 if( begin > end )
00252 return begin;
00253
00254 if( !btohs(field->size) )
00255 return begin;
00256
00257
00258 for( FieldLink<ServiceBook> *b = ServiceBookFieldLinks;
00259 b->type != SBFC_END;
00260 b++ )
00261 {
00262 if( b->type == field->type ) {
00263 if( b->strMember ) {
00264 std::string &s = this->*(b->strMember);
00265 s = ParseFieldString(field);
00266 return begin;
00267 }
00268 else if( b->timeMember && btohs(field->size) == 4 ) {
00269 time_t &t = this->*(b->timeMember);
00270 t = min2time(field->u.min1900);
00271 return begin;
00272 }
00273 }
00274 }
00275
00276
00277 switch( field->type )
00278 {
00279 case SBFC_OLD_NAME:
00280 case SBFC_NAME:
00281 Name = ParseFieldString(field);
00282 NameType = field->type;
00283 return begin;
00284
00285 case SBFC_OLD_DESC:
00286 case SBFC_DESCRIPTION:
00287 Description = ParseFieldString(field);
00288 DescType = field->type;
00289 return begin;
00290
00291 case SBFC_OLD_UNIQUE_ID:
00292 case SBFC_UNIQUE_ID:
00293 UniqueId = ParseFieldString(field);
00294 UniqueIdType = field->type;
00295 return begin;
00296
00297 case SBFC_CONTENT_ID:
00298 ContentId = ParseFieldString(field);
00299 return begin;
00300
00301 case SBFC_BES_DOMAIN:
00302 BesDomain = ParseFieldString(field);
00303 return begin;
00304
00305 case SBFC_CONFIG:
00306 {
00307 Data config((const void *)field->u.raw, btohs(field->size));
00308 size_t offset = 0;
00309 Config.ParseHeader(config, offset);
00310 Config.ParseFields(config, offset);
00311 }
00312 break;
00313
00314 }
00315
00316
00317 UnknownField uf;
00318 uf.type = field->type;
00319 uf.data.assign((const char*)field->u.raw, btohs(field->size));
00320 Unknowns.push_back(uf);
00321
00322
00323 return begin;
00324 }
00325
00326 void ServiceBook::ParseHeader(const Data &data, size_t &offset)
00327 {
00328
00329 }
00330
00331 void ServiceBook::ParseFields(const Data &data, size_t &offset)
00332 {
00333 const unsigned char *finish = ParseCommonFields(*this,
00334 data.GetData() + offset, data.GetData() + data.GetSize());
00335 offset += finish - (data.GetData() + offset);
00336 }
00337
00338 void ServiceBook::BuildHeader(Data &data, size_t &offset) const
00339 {
00340
00341 }
00342
00343
00344
00345
00346
00347
00348 void ServiceBook::BuildFields(Data &data, size_t &offset) const
00349 {
00350 throw std::logic_error("ServiceBook::BuildFields not yet implemented");
00351 }
00352
00353 void ServiceBook::Clear()
00354 {
00355 Unknowns.clear();
00356 Config.Clear();
00357 }
00358
00359 void ServiceBook::Dump(std::ostream &os) const
00360 {
00361 os << "ServiceBook entry: 0x" << setbase(16) << RecordId
00362 << " (" << (unsigned int)RecType << ")\n";
00363
00364
00365 for( const FieldLink<ServiceBook> *b = ServiceBookFieldLinks;
00366 b->type != SBFC_END;
00367 b++ )
00368 {
00369 if( b->strMember ) {
00370 const std::string &s = this->*(b->strMember);
00371 if( s.size() )
00372 os << " " << b->name << ": " << s << "\n";
00373 }
00374 else if( b->timeMember ) {
00375 time_t t = this->*(b->timeMember);
00376 if( t > 0 )
00377 os << " " << b->name << ": " << ctime(&t);
00378 }
00379 }
00380
00381
00382 if( UniqueId.size() )
00383 os << " Unique ID: " << UniqueId << "\n";
00384 if( ContentId.size() )
00385 os << " Content ID: " << ContentId << "\n";
00386 if( BesDomain.size() )
00387 os << " (BES) Domain: " << BesDomain << "\n";
00388
00389 os << Config;
00390
00391
00392 os << Unknowns;
00393 }
00394
00395 }
00396