This source file includes following definitions.
- command_2_index
- capi_cmd2par
- jumpcstruct
- pars_2_message
- capi_cmsg2message
- message_2_pars
- capi_message2cmsg
- capi_cmsg_header
- capi_cmd2str
- bufprint
- printstructlen
- printstruct
- protocol_message_2_pars
- cdebbuf_alloc
- cdebbuf_free
- capi_message2str
- capi_cmsg2str
- cdebug_init
- cdebug_exit
- capi_message2str
- capi_cmsg2str
- cdebbuf_free
- cdebug_init
- cdebug_exit
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 #include <linux/module.h>
  14 #include <linux/string.h>
  15 #include <linux/ctype.h>
  16 #include <linux/stddef.h>
  17 #include <linux/kernel.h>
  18 #include <linux/mm.h>
  19 #include <linux/init.h>
  20 #include <linux/isdn/capiutil.h>
  21 #include <linux/slab.h>
  22 
  23 
  24 
  25 typedef struct {
  26         int typ;
  27         size_t off;
  28 } _cdef;
  29 
  30 #define _CBYTE         1
  31 #define _CWORD         2
  32 #define _CDWORD        3
  33 #define _CSTRUCT       4
  34 #define _CMSTRUCT      5
  35 #define _CEND          6
  36 
  37 static _cdef cdef[] =
  38 {
  39         
  40         {_CEND},
  41         
  42         {_CEND},
  43         
  44         {_CEND},
  45         
  46         {_CDWORD, offsetof(_cmsg, adr.adrController)},
  47         
  48         {_CMSTRUCT, offsetof(_cmsg, AdditionalInfo)},
  49         
  50         {_CSTRUCT, offsetof(_cmsg, B1configuration)},
  51         
  52         {_CWORD, offsetof(_cmsg, B1protocol)},
  53         
  54         {_CSTRUCT, offsetof(_cmsg, B2configuration)},
  55         
  56         {_CWORD, offsetof(_cmsg, B2protocol)},
  57         
  58         {_CSTRUCT, offsetof(_cmsg, B3configuration)},
  59         
  60         {_CWORD, offsetof(_cmsg, B3protocol)},
  61         
  62         {_CSTRUCT, offsetof(_cmsg, BC)},
  63         
  64         {_CSTRUCT, offsetof(_cmsg, BChannelinformation)},
  65         
  66         {_CMSTRUCT, offsetof(_cmsg, BProtocol)},
  67         
  68         {_CSTRUCT, offsetof(_cmsg, CalledPartyNumber)},
  69         
  70         {_CSTRUCT, offsetof(_cmsg, CalledPartySubaddress)},
  71         
  72         {_CSTRUCT, offsetof(_cmsg, CallingPartyNumber)},
  73         
  74         {_CSTRUCT, offsetof(_cmsg, CallingPartySubaddress)},
  75         
  76         {_CDWORD, offsetof(_cmsg, CIPmask)},
  77         
  78         {_CDWORD, offsetof(_cmsg, CIPmask2)},
  79         
  80         {_CWORD, offsetof(_cmsg, CIPValue)},
  81         
  82         {_CDWORD, offsetof(_cmsg, Class)},
  83         
  84         {_CSTRUCT, offsetof(_cmsg, ConnectedNumber)},
  85         
  86         {_CSTRUCT, offsetof(_cmsg, ConnectedSubaddress)},
  87         
  88         {_CDWORD, offsetof(_cmsg, Data)},
  89         
  90         {_CWORD, offsetof(_cmsg, DataHandle)},
  91         
  92         {_CWORD, offsetof(_cmsg, DataLength)},
  93         
  94         {_CSTRUCT, offsetof(_cmsg, FacilityConfirmationParameter)},
  95         
  96         {_CSTRUCT, offsetof(_cmsg, Facilitydataarray)},
  97         
  98         {_CSTRUCT, offsetof(_cmsg, FacilityIndicationParameter)},
  99         
 100         {_CSTRUCT, offsetof(_cmsg, FacilityRequestParameter)},
 101         
 102         {_CWORD, offsetof(_cmsg, FacilitySelector)},
 103         
 104         {_CWORD, offsetof(_cmsg, Flags)},
 105         
 106         {_CDWORD, offsetof(_cmsg, Function)},
 107         
 108         {_CSTRUCT, offsetof(_cmsg, HLC)},
 109         
 110         {_CWORD, offsetof(_cmsg, Info)},
 111         
 112         {_CSTRUCT, offsetof(_cmsg, InfoElement)},
 113         
 114         {_CDWORD, offsetof(_cmsg, InfoMask)},
 115         
 116         {_CWORD, offsetof(_cmsg, InfoNumber)},
 117         
 118         {_CSTRUCT, offsetof(_cmsg, Keypadfacility)},
 119         
 120         {_CSTRUCT, offsetof(_cmsg, LLC)},
 121         
 122         {_CSTRUCT, offsetof(_cmsg, ManuData)},
 123         
 124         {_CDWORD, offsetof(_cmsg, ManuID)},
 125         
 126         {_CSTRUCT, offsetof(_cmsg, NCPI)},
 127         
 128         {_CWORD, offsetof(_cmsg, Reason)},
 129         
 130         {_CWORD, offsetof(_cmsg, Reason_B3)},
 131         
 132         {_CWORD, offsetof(_cmsg, Reject)},
 133         
 134         {_CSTRUCT, offsetof(_cmsg, Useruserdata)}
 135 };
 136 
 137 static unsigned char *cpars[] =
 138 {
 139          [0x01] = "\x03\x04\x0c\x27\x2f\x1c\x01\x01",
 140          [0x02] = "\x03\x14\x0e\x10\x0f\x11\x0d\x06\x08\x0a\x05\x07\x09\x01\x0b\x28\x22\x04\x0c\x27\x2f\x1c\x01\x01",
 141          [0x04] = "\x03\x04\x0c\x27\x2f\x1c\x01\x01",
 142          [0x05] = "\x03\x25\x12\x13\x10\x11\x01",
 143          [0x08] = "\x03\x0e\x04\x0c\x27\x2f\x1c\x01\x01",
 144          [0x09] = "\x03\x1f\x1e\x01",
 145          [0x0a] = "\x03\x0d\x06\x08\x0a\x05\x07\x09\x01\x01",
 146          [0x0b] = "\x03\x2b\x01",
 147          [0x0d] = "\x03\x2b\x01",
 148          [0x0f] = "\x03\x18\x1a\x19\x20\x01",
 149          [0x10] = "\x03\x2b\x01",
 150          [0x13] = "\x03\x23\x01",
 151          [0x14] = "\x03\x23\x01",
 152          [0x16] = "\x03\x23\x01",
 153          [0x17] = "\x03\x23\x01",
 154          [0x18] = "\x03\x2a\x15\x21\x29\x01",
 155          [0x1a] = "\x03\x23\x01",
 156          [0x1b] = "\x03\x23\x1f\x1b\x01",
 157          [0x1c] = "\x03\x23\x01",
 158          [0x1d] = "\x03\x23\x01",
 159          [0x1f] = "\x03\x23\x01",
 160          [0x21] = "\x03\x19\x23\x01",
 161          [0x22] = "\x03\x23\x01",
 162          [0x26] = "\x03\x14\x0e\x10\x0f\x11\x0b\x28\x22\x04\x0c\x27\x2f\x1c\x01\x01",
 163          [0x27] = "\x03\x16\x17\x28\x01",
 164          [0x28] = "\x03\x2c\x01",
 165          [0x2a] = "\x03\x2a\x15\x21\x29\x01",
 166          [0x2c] = "\x03\x26\x24\x01",
 167          [0x2d] = "\x03\x1f\x1d\x01",
 168          [0x2f] = "\x03\x2b\x01",
 169          [0x30] = "\x03\x2b\x01",
 170          [0x31] = "\x03\x2d\x2b\x01",
 171          [0x33] = "\x03\x18\x1a\x19\x20\x01",
 172          [0x34] = "\x03\x2b\x01",
 173          [0x35] = "\x03\x2b\x01",
 174          [0x38] = "\x03\x2e\x0d\x06\x08\x0a\x05\x07\x09\x01\x16\x17\x28\x04\x0c\x27\x2f\x1c\x01\x01",
 175          [0x39] = "\x03\x01",
 176          [0x3a] = "\x03\x01",
 177          [0x3c] = "\x03\x2a\x15\x21\x29\x01",
 178          [0x3e] = "\x03\x01",
 179          [0x3f] = "\x03\x1f\x01",
 180          [0x41] = "\x03\x2e\x2b\x01",
 181          [0x42] = "\x03\x01",
 182          [0x43] = "\x03\x01",
 183          [0x45] = "\x03\x19\x01",
 184          [0x46] = "\x03\x01",
 185          [0x47] = "\x03\x01",
 186          [0x4e] = "\x03\x2a\x15\x21\x29\x01",
 187 };
 188 
 189 
 190 
 191 #define byteTLcpy(x, y)         *(u8 *)(x) = *(u8 *)(y);
 192 #define wordTLcpy(x, y)         *(u16 *)(x) = *(u16 *)(y);
 193 #define dwordTLcpy(x, y)        memcpy(x, y, 4);
 194 #define structTLcpy(x, y, l)    memcpy(x, y, l)
 195 #define structTLcpyovl(x, y, l) memmove(x, y, l)
 196 
 197 #define byteTRcpy(x, y)         *(u8 *)(y) = *(u8 *)(x);
 198 #define wordTRcpy(x, y)         *(u16 *)(y) = *(u16 *)(x);
 199 #define dwordTRcpy(x, y)        memcpy(y, x, 4);
 200 #define structTRcpy(x, y, l)    memcpy(y, x, l)
 201 #define structTRcpyovl(x, y, l) memmove(y, x, l)
 202 
 203 
 204 static unsigned command_2_index(u8 c, u8 sc)
 205 {
 206         if (c & 0x80)
 207                 c = 0x9 + (c & 0x0f);
 208         else if (c == 0x41)
 209                 c = 0x9 + 0x1;
 210         if (c > 0x18)
 211                 c = 0x00;
 212         return (sc & 3) * (0x9 + 0x9) + c;
 213 }
 214 
 215 
 216 
 217 
 218 
 219 
 220 
 221 
 222 
 223 static unsigned char *capi_cmd2par(u8 cmd, u8 subcmd)
 224 {
 225         return cpars[command_2_index(cmd, subcmd)];
 226 }
 227 
 228 
 229 #define TYP (cdef[cmsg->par[cmsg->p]].typ)
 230 #define OFF (((u8 *)cmsg) + cdef[cmsg->par[cmsg->p]].off)
 231 
 232 static void jumpcstruct(_cmsg *cmsg)
 233 {
 234         unsigned layer;
 235         for (cmsg->p++, layer = 1; layer;) {
 236                 
 237                 cmsg->p++;
 238                 switch (TYP) {
 239                 case _CMSTRUCT:
 240                         layer++;
 241                         break;
 242                 case _CEND:
 243                         layer--;
 244                         break;
 245                 }
 246         }
 247 }
 248 
 249 static void pars_2_message(_cmsg *cmsg)
 250 {
 251 
 252         for (; TYP != _CEND; cmsg->p++) {
 253                 switch (TYP) {
 254                 case _CBYTE:
 255                         byteTLcpy(cmsg->m + cmsg->l, OFF);
 256                         cmsg->l++;
 257                         break;
 258                 case _CWORD:
 259                         wordTLcpy(cmsg->m + cmsg->l, OFF);
 260                         cmsg->l += 2;
 261                         break;
 262                 case _CDWORD:
 263                         dwordTLcpy(cmsg->m + cmsg->l, OFF);
 264                         cmsg->l += 4;
 265                         break;
 266                 case _CSTRUCT:
 267                         if (*(u8 **) OFF == NULL) {
 268                                 *(cmsg->m + cmsg->l) = '\0';
 269                                 cmsg->l++;
 270                         } else if (**(_cstruct *) OFF != 0xff) {
 271                                 structTLcpy(cmsg->m + cmsg->l, *(_cstruct *) OFF, 1 + **(_cstruct *) OFF);
 272                                 cmsg->l += 1 + **(_cstruct *) OFF;
 273                         } else {
 274                                 _cstruct s = *(_cstruct *) OFF;
 275                                 structTLcpy(cmsg->m + cmsg->l, s, 3 + *(u16 *) (s + 1));
 276                                 cmsg->l += 3 + *(u16 *) (s + 1);
 277                         }
 278                         break;
 279                 case _CMSTRUCT:
 280 
 281                         if (*(_cmstruct *) OFF == CAPI_DEFAULT) {
 282                                 *(cmsg->m + cmsg->l) = '\0';
 283                                 cmsg->l++;
 284                                 jumpcstruct(cmsg);
 285                         }
 286 
 287                         else {
 288                                 unsigned _l = cmsg->l;
 289                                 unsigned _ls;
 290                                 cmsg->l++;
 291                                 cmsg->p++;
 292                                 pars_2_message(cmsg);
 293                                 _ls = cmsg->l - _l - 1;
 294                                 if (_ls < 255)
 295                                         (cmsg->m + _l)[0] = (u8) _ls;
 296                                 else {
 297                                         structTLcpyovl(cmsg->m + _l + 3, cmsg->m + _l + 1, _ls);
 298                                         (cmsg->m + _l)[0] = 0xff;
 299                                         wordTLcpy(cmsg->m + _l + 1, &_ls);
 300                                 }
 301                         }
 302                         break;
 303                 }
 304         }
 305 }
 306 
 307 
 308 
 309 
 310 
 311 
 312 
 313 
 314 
 315 unsigned capi_cmsg2message(_cmsg *cmsg, u8 *msg)
 316 {
 317         cmsg->m = msg;
 318         cmsg->l = 8;
 319         cmsg->p = 0;
 320         cmsg->par = capi_cmd2par(cmsg->Command, cmsg->Subcommand);
 321         if (!cmsg->par)
 322                 return 1;       
 323 
 324         pars_2_message(cmsg);
 325 
 326         wordTLcpy(msg + 0, &cmsg->l);
 327         byteTLcpy(cmsg->m + 4, &cmsg->Command);
 328         byteTLcpy(cmsg->m + 5, &cmsg->Subcommand);
 329         wordTLcpy(cmsg->m + 2, &cmsg->ApplId);
 330         wordTLcpy(cmsg->m + 6, &cmsg->Messagenumber);
 331 
 332         return 0;
 333 }
 334 
 335 
 336 static void message_2_pars(_cmsg *cmsg)
 337 {
 338         for (; TYP != _CEND; cmsg->p++) {
 339 
 340                 switch (TYP) {
 341                 case _CBYTE:
 342                         byteTRcpy(cmsg->m + cmsg->l, OFF);
 343                         cmsg->l++;
 344                         break;
 345                 case _CWORD:
 346                         wordTRcpy(cmsg->m + cmsg->l, OFF);
 347                         cmsg->l += 2;
 348                         break;
 349                 case _CDWORD:
 350                         dwordTRcpy(cmsg->m + cmsg->l, OFF);
 351                         cmsg->l += 4;
 352                         break;
 353                 case _CSTRUCT:
 354                         *(u8 **) OFF = cmsg->m + cmsg->l;
 355 
 356                         if (cmsg->m[cmsg->l] != 0xff)
 357                                 cmsg->l += 1 + cmsg->m[cmsg->l];
 358                         else
 359                                 cmsg->l += 3 + *(u16 *) (cmsg->m + cmsg->l + 1);
 360                         break;
 361                 case _CMSTRUCT:
 362 
 363                         if (cmsg->m[cmsg->l] == '\0') {
 364                                 *(_cmstruct *) OFF = CAPI_DEFAULT;
 365                                 cmsg->l++;
 366                                 jumpcstruct(cmsg);
 367                         } else {
 368                                 unsigned _l = cmsg->l;
 369                                 *(_cmstruct *) OFF = CAPI_COMPOSE;
 370                                 cmsg->l = (cmsg->m + _l)[0] == 255 ? cmsg->l + 3 : cmsg->l + 1;
 371                                 cmsg->p++;
 372                                 message_2_pars(cmsg);
 373                         }
 374                         break;
 375                 }
 376         }
 377 }
 378 
 379 
 380 
 381 
 382 
 383 
 384 
 385 
 386 
 387 unsigned capi_message2cmsg(_cmsg *cmsg, u8 *msg)
 388 {
 389         memset(cmsg, 0, sizeof(_cmsg));
 390         cmsg->m = msg;
 391         cmsg->l = 8;
 392         cmsg->p = 0;
 393         byteTRcpy(cmsg->m + 4, &cmsg->Command);
 394         byteTRcpy(cmsg->m + 5, &cmsg->Subcommand);
 395         cmsg->par = capi_cmd2par(cmsg->Command, cmsg->Subcommand);
 396         if (!cmsg->par)
 397                 return 1;       
 398 
 399         message_2_pars(cmsg);
 400 
 401         wordTRcpy(msg + 0, &cmsg->l);
 402         wordTRcpy(cmsg->m + 2, &cmsg->ApplId);
 403         wordTRcpy(cmsg->m + 6, &cmsg->Messagenumber);
 404 
 405         return 0;
 406 }
 407 
 408 
 409 
 410 
 411 
 412 
 413 
 414 
 415 
 416 
 417 
 418 
 419 
 420 unsigned capi_cmsg_header(_cmsg *cmsg, u16 _ApplId,
 421                           u8 _Command, u8 _Subcommand,
 422                           u16 _Messagenumber, u32 _Controller)
 423 {
 424         memset(cmsg, 0, sizeof(_cmsg));
 425         cmsg->ApplId = _ApplId;
 426         cmsg->Command = _Command;
 427         cmsg->Subcommand = _Subcommand;
 428         cmsg->Messagenumber = _Messagenumber;
 429         cmsg->adr.adrController = _Controller;
 430         return 0;
 431 }
 432 
 433 
 434 
 435 static char *mnames[] =
 436 {
 437         [0x01] = "ALERT_REQ",
 438         [0x02] = "CONNECT_REQ",
 439         [0x04] = "DISCONNECT_REQ",
 440         [0x05] = "LISTEN_REQ",
 441         [0x08] = "INFO_REQ",
 442         [0x09] = "FACILITY_REQ",
 443         [0x0a] = "SELECT_B_PROTOCOL_REQ",
 444         [0x0b] = "CONNECT_B3_REQ",
 445         [0x0d] = "DISCONNECT_B3_REQ",
 446         [0x0f] = "DATA_B3_REQ",
 447         [0x10] = "RESET_B3_REQ",
 448         [0x13] = "ALERT_CONF",
 449         [0x14] = "CONNECT_CONF",
 450         [0x16] = "DISCONNECT_CONF",
 451         [0x17] = "LISTEN_CONF",
 452         [0x18] = "MANUFACTURER_REQ",
 453         [0x1a] = "INFO_CONF",
 454         [0x1b] = "FACILITY_CONF",
 455         [0x1c] = "SELECT_B_PROTOCOL_CONF",
 456         [0x1d] = "CONNECT_B3_CONF",
 457         [0x1f] = "DISCONNECT_B3_CONF",
 458         [0x21] = "DATA_B3_CONF",
 459         [0x22] = "RESET_B3_CONF",
 460         [0x26] = "CONNECT_IND",
 461         [0x27] = "CONNECT_ACTIVE_IND",
 462         [0x28] = "DISCONNECT_IND",
 463         [0x2a] = "MANUFACTURER_CONF",
 464         [0x2c] = "INFO_IND",
 465         [0x2d] = "FACILITY_IND",
 466         [0x2f] = "CONNECT_B3_IND",
 467         [0x30] = "CONNECT_B3_ACTIVE_IND",
 468         [0x31] = "DISCONNECT_B3_IND",
 469         [0x33] = "DATA_B3_IND",
 470         [0x34] = "RESET_B3_IND",
 471         [0x35] = "CONNECT_B3_T90_ACTIVE_IND",
 472         [0x38] = "CONNECT_RESP",
 473         [0x39] = "CONNECT_ACTIVE_RESP",
 474         [0x3a] = "DISCONNECT_RESP",
 475         [0x3c] = "MANUFACTURER_IND",
 476         [0x3e] = "INFO_RESP",
 477         [0x3f] = "FACILITY_RESP",
 478         [0x41] = "CONNECT_B3_RESP",
 479         [0x42] = "CONNECT_B3_ACTIVE_RESP",
 480         [0x43] = "DISCONNECT_B3_RESP",
 481         [0x45] = "DATA_B3_RESP",
 482         [0x46] = "RESET_B3_RESP",
 483         [0x47] = "CONNECT_B3_T90_ACTIVE_RESP",
 484         [0x4e] = "MANUFACTURER_RESP"
 485 };
 486 
 487 
 488 
 489 
 490 
 491 
 492 
 493 
 494 
 495 char *capi_cmd2str(u8 cmd, u8 subcmd)
 496 {
 497         char *result;
 498 
 499         result = mnames[command_2_index(cmd, subcmd)];
 500         if (result == NULL)
 501                 result = "INVALID_COMMAND";
 502         return result;
 503 }
 504 
 505 
 506 
 507 
 508 #ifdef CONFIG_CAPI_TRACE
 509 
 510 
 511 
 512 static char *pnames[] =
 513 {
 514          NULL,
 515          NULL,
 516          NULL,
 517          "Controller/PLCI/NCCI",
 518          "AdditionalInfo",
 519          "B1configuration",
 520          "B1protocol",
 521          "B2configuration",
 522          "B2protocol",
 523          "B3configuration",
 524          "B3protocol",
 525          "BC",
 526          "BChannelinformation",
 527          "BProtocol",
 528          "CalledPartyNumber",
 529          "CalledPartySubaddress",
 530          "CallingPartyNumber",
 531          "CallingPartySubaddress",
 532          "CIPmask",
 533          "CIPmask2",
 534          "CIPValue",
 535          "Class",
 536          "ConnectedNumber",
 537          "ConnectedSubaddress",
 538          "Data32",
 539          "DataHandle",
 540          "DataLength",
 541          "FacilityConfirmationParameter",
 542          "Facilitydataarray",
 543          "FacilityIndicationParameter",
 544          "FacilityRequestParameter",
 545          "FacilitySelector",
 546          "Flags",
 547          "Function",
 548          "HLC",
 549          "Info",
 550          "InfoElement",
 551          "InfoMask",
 552          "InfoNumber",
 553          "Keypadfacility",
 554          "LLC",
 555          "ManuData",
 556          "ManuID",
 557          "NCPI",
 558          "Reason",
 559          "Reason_B3",
 560          "Reject",
 561          "Useruserdata"
 562 };
 563 
 564 
 565 
 566 #include <stdarg.h>
 567 
 568 
 569 static _cdebbuf *bufprint(_cdebbuf *cdb, char *fmt, ...)
 570 {
 571         va_list f;
 572         size_t n, r;
 573 
 574         if (!cdb)
 575                 return NULL;
 576         va_start(f, fmt);
 577         r = cdb->size - cdb->pos;
 578         n = vsnprintf(cdb->p, r, fmt, f);
 579         va_end(f);
 580         if (n >= r) {
 581                 
 582                 size_t ns = 2 * cdb->size;
 583                 u_char *nb;
 584 
 585                 while ((ns - cdb->pos) <= n)
 586                         ns *= 2;
 587                 nb = kmalloc(ns, GFP_ATOMIC);
 588                 if (!nb) {
 589                         cdebbuf_free(cdb);
 590                         return NULL;
 591                 }
 592                 memcpy(nb, cdb->buf, cdb->pos);
 593                 kfree(cdb->buf);
 594                 nb[cdb->pos] = 0;
 595                 cdb->buf = nb;
 596                 cdb->p = cdb->buf + cdb->pos;
 597                 cdb->size = ns;
 598                 va_start(f, fmt);
 599                 r = cdb->size - cdb->pos;
 600                 n = vsnprintf(cdb->p, r, fmt, f);
 601                 va_end(f);
 602         }
 603         cdb->p += n;
 604         cdb->pos += n;
 605         return cdb;
 606 }
 607 
 608 static _cdebbuf *printstructlen(_cdebbuf *cdb, u8 *m, unsigned len)
 609 {
 610         unsigned hex = 0;
 611 
 612         if (!cdb)
 613                 return NULL;
 614         for (; len; len--, m++)
 615                 if (isalnum(*m) || *m == ' ') {
 616                         if (hex)
 617                                 cdb = bufprint(cdb, ">");
 618                         cdb = bufprint(cdb, "%c", *m);
 619                         hex = 0;
 620                 } else {
 621                         if (!hex)
 622                                 cdb = bufprint(cdb, "<%02x", *m);
 623                         else
 624                                 cdb = bufprint(cdb, " %02x", *m);
 625                         hex = 1;
 626                 }
 627         if (hex)
 628                 cdb = bufprint(cdb, ">");
 629         return cdb;
 630 }
 631 
 632 static _cdebbuf *printstruct(_cdebbuf *cdb, u8 *m)
 633 {
 634         unsigned len;
 635 
 636         if (m[0] != 0xff) {
 637                 len = m[0];
 638                 m += 1;
 639         } else {
 640                 len = ((u16 *) (m + 1))[0];
 641                 m += 3;
 642         }
 643         cdb = printstructlen(cdb, m, len);
 644         return cdb;
 645 }
 646 
 647 
 648 #define NAME (pnames[cmsg->par[cmsg->p]])
 649 
 650 static _cdebbuf *protocol_message_2_pars(_cdebbuf *cdb, _cmsg *cmsg, int level)
 651 {
 652         if (!cmsg->par)
 653                 return NULL;    
 654 
 655         for (; TYP != _CEND; cmsg->p++) {
 656                 int slen = 29 + 3 - level;
 657                 int i;
 658 
 659                 if (!cdb)
 660                         return NULL;
 661                 cdb = bufprint(cdb, "  ");
 662                 for (i = 0; i < level - 1; i++)
 663                         cdb = bufprint(cdb, " ");
 664 
 665                 switch (TYP) {
 666                 case _CBYTE:
 667                         cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u8 *) (cmsg->m + cmsg->l));
 668                         cmsg->l++;
 669                         break;
 670                 case _CWORD:
 671                         cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u16 *) (cmsg->m + cmsg->l));
 672                         cmsg->l += 2;
 673                         break;
 674                 case _CDWORD:
 675                         cdb = bufprint(cdb, "%-*s = 0x%lx\n", slen, NAME, *(u32 *) (cmsg->m + cmsg->l));
 676                         cmsg->l += 4;
 677                         break;
 678                 case _CSTRUCT:
 679                         cdb = bufprint(cdb, "%-*s = ", slen, NAME);
 680                         if (cmsg->m[cmsg->l] == '\0')
 681                                 cdb = bufprint(cdb, "default");
 682                         else
 683                                 cdb = printstruct(cdb, cmsg->m + cmsg->l);
 684                         cdb = bufprint(cdb, "\n");
 685                         if (cmsg->m[cmsg->l] != 0xff)
 686                                 cmsg->l += 1 + cmsg->m[cmsg->l];
 687                         else
 688                                 cmsg->l += 3 + *(u16 *) (cmsg->m + cmsg->l + 1);
 689 
 690                         break;
 691 
 692                 case _CMSTRUCT:
 693 
 694                         if (cmsg->m[cmsg->l] == '\0') {
 695                                 cdb = bufprint(cdb, "%-*s = default\n", slen, NAME);
 696                                 cmsg->l++;
 697                                 jumpcstruct(cmsg);
 698                         } else {
 699                                 char *name = NAME;
 700                                 unsigned _l = cmsg->l;
 701                                 cdb = bufprint(cdb, "%-*s\n", slen, name);
 702                                 cmsg->l = (cmsg->m + _l)[0] == 255 ? cmsg->l + 3 : cmsg->l + 1;
 703                                 cmsg->p++;
 704                                 cdb = protocol_message_2_pars(cdb, cmsg, level + 1);
 705                         }
 706                         break;
 707                 }
 708         }
 709         return cdb;
 710 }
 711 
 712 
 713 static _cdebbuf *g_debbuf;
 714 static u_long g_debbuf_lock;
 715 static _cmsg *g_cmsg;
 716 
 717 static _cdebbuf *cdebbuf_alloc(void)
 718 {
 719         _cdebbuf *cdb;
 720 
 721         if (likely(!test_and_set_bit(1, &g_debbuf_lock))) {
 722                 cdb = g_debbuf;
 723                 goto init;
 724         } else
 725                 cdb = kmalloc(sizeof(_cdebbuf), GFP_ATOMIC);
 726         if (!cdb)
 727                 return NULL;
 728         cdb->buf = kmalloc(CDEBUG_SIZE, GFP_ATOMIC);
 729         if (!cdb->buf) {
 730                 kfree(cdb);
 731                 return NULL;
 732         }
 733         cdb->size = CDEBUG_SIZE;
 734 init:
 735         cdb->buf[0] = 0;
 736         cdb->p = cdb->buf;
 737         cdb->pos = 0;
 738         return cdb;
 739 }
 740 
 741 
 742 
 743 
 744 
 745 
 746 void cdebbuf_free(_cdebbuf *cdb)
 747 {
 748         if (likely(cdb == g_debbuf)) {
 749                 test_and_clear_bit(1, &g_debbuf_lock);
 750                 return;
 751         }
 752         if (likely(cdb))
 753                 kfree(cdb->buf);
 754         kfree(cdb);
 755 }
 756 
 757 
 758 
 759 
 760 
 761 
 762 
 763 
 764 
 765 
 766 
 767 
 768 _cdebbuf *capi_message2str(u8 *msg)
 769 {
 770         _cdebbuf *cdb;
 771         _cmsg   *cmsg;
 772 
 773         cdb = cdebbuf_alloc();
 774         if (unlikely(!cdb))
 775                 return NULL;
 776         if (likely(cdb == g_debbuf))
 777                 cmsg = g_cmsg;
 778         else
 779                 cmsg = kmalloc(sizeof(_cmsg), GFP_ATOMIC);
 780         if (unlikely(!cmsg)) {
 781                 cdebbuf_free(cdb);
 782                 return NULL;
 783         }
 784         cmsg->m = msg;
 785         cmsg->l = 8;
 786         cmsg->p = 0;
 787         byteTRcpy(cmsg->m + 4, &cmsg->Command);
 788         byteTRcpy(cmsg->m + 5, &cmsg->Subcommand);
 789         cmsg->par = capi_cmd2par(cmsg->Command, cmsg->Subcommand);
 790 
 791         cdb = bufprint(cdb, "%-26s ID=%03d #0x%04x LEN=%04d\n",
 792                        capi_cmd2str(cmsg->Command, cmsg->Subcommand),
 793                        ((unsigned short *) msg)[1],
 794                        ((unsigned short *) msg)[3],
 795                        ((unsigned short *) msg)[0]);
 796 
 797         cdb = protocol_message_2_pars(cdb, cmsg, 1);
 798         if (unlikely(cmsg != g_cmsg))
 799                 kfree(cmsg);
 800         return cdb;
 801 }
 802 
 803 
 804 
 805 
 806 
 807 
 808 
 809 
 810 
 811 
 812 
 813 
 814 _cdebbuf *capi_cmsg2str(_cmsg *cmsg)
 815 {
 816         _cdebbuf *cdb;
 817 
 818         if (!cmsg->m)
 819                 return NULL;    
 820         cdb = cdebbuf_alloc();
 821         if (!cdb)
 822                 return NULL;
 823         cmsg->l = 8;
 824         cmsg->p = 0;
 825         cdb = bufprint(cdb, "%s ID=%03d #0x%04x LEN=%04d\n",
 826                        capi_cmd2str(cmsg->Command, cmsg->Subcommand),
 827                        ((u16 *) cmsg->m)[1],
 828                        ((u16 *) cmsg->m)[3],
 829                        ((u16 *) cmsg->m)[0]);
 830         cdb = protocol_message_2_pars(cdb, cmsg, 1);
 831         return cdb;
 832 }
 833 
 834 int __init cdebug_init(void)
 835 {
 836         g_cmsg = kmalloc(sizeof(_cmsg), GFP_KERNEL);
 837         if (!g_cmsg)
 838                 return -ENOMEM;
 839         g_debbuf = kmalloc(sizeof(_cdebbuf), GFP_KERNEL);
 840         if (!g_debbuf) {
 841                 kfree(g_cmsg);
 842                 return -ENOMEM;
 843         }
 844         g_debbuf->buf = kmalloc(CDEBUG_GSIZE, GFP_KERNEL);
 845         if (!g_debbuf->buf) {
 846                 kfree(g_cmsg);
 847                 kfree(g_debbuf);
 848                 return -ENOMEM;
 849         }
 850         g_debbuf->size = CDEBUG_GSIZE;
 851         g_debbuf->buf[0] = 0;
 852         g_debbuf->p = g_debbuf->buf;
 853         g_debbuf->pos = 0;
 854         return 0;
 855 }
 856 
 857 void __exit cdebug_exit(void)
 858 {
 859         if (g_debbuf)
 860                 kfree(g_debbuf->buf);
 861         kfree(g_debbuf);
 862         kfree(g_cmsg);
 863 }
 864 
 865 #else 
 866 
 867 static _cdebbuf g_debbuf = {"CONFIG_CAPI_TRACE not enabled", NULL, 0, 0};
 868 
 869 _cdebbuf *capi_message2str(u8 *msg)
 870 {
 871         return &g_debbuf;
 872 }
 873 
 874 _cdebbuf *capi_cmsg2str(_cmsg *cmsg)
 875 {
 876         return &g_debbuf;
 877 }
 878 
 879 void cdebbuf_free(_cdebbuf *cdb)
 880 {
 881 }
 882 
 883 int __init cdebug_init(void)
 884 {
 885         return 0;
 886 }
 887 
 888 void __exit cdebug_exit(void)
 889 {
 890 }
 891 
 892 #endif
 893 
 894 EXPORT_SYMBOL(cdebbuf_free);
 895 EXPORT_SYMBOL(capi_cmsg2message);
 896 EXPORT_SYMBOL(capi_message2cmsg);
 897 EXPORT_SYMBOL(capi_cmsg_header);
 898 EXPORT_SYMBOL(capi_cmd2str);
 899 EXPORT_SYMBOL(capi_cmsg2str);
 900 EXPORT_SYMBOL(capi_message2str);