sdp.c 112 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2001-2002 Nokia Corporation
  7. * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
  8. * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
  9. * Copyright (C) 2002-2003 Stephen Crane <steve.crane@rococosoft.com>
  10. *
  11. *
  12. */
  13. #ifdef HAVE_CONFIG_H
  14. #include <config.h>
  15. #endif
  16. #include <stdio.h>
  17. #include <errno.h>
  18. #include <fcntl.h>
  19. #include <unistd.h>
  20. #include <stdlib.h>
  21. #include <limits.h>
  22. #include <string.h>
  23. #include <syslog.h>
  24. #include <sys/time.h>
  25. #include <sys/types.h>
  26. #include <sys/socket.h>
  27. #include <sys/un.h>
  28. #include <netinet/in.h>
  29. #include "bluetooth.h"
  30. #include "hci.h"
  31. #include "hci_lib.h"
  32. #include "l2cap.h"
  33. #include "sdp.h"
  34. #include "sdp_lib.h"
  35. #define SDPINF(fmt, arg...) syslog(LOG_INFO, fmt "\n", ## arg)
  36. #define SDPERR(fmt, arg...) syslog(LOG_ERR, "%s: " fmt "\n", __func__ , ## arg)
  37. #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
  38. #ifdef SDP_DEBUG
  39. #define SDPDBG(fmt, arg...) syslog(LOG_DEBUG, "%s: " fmt "\n", __func__ , ## arg)
  40. #else
  41. #define SDPDBG(fmt...)
  42. #endif
  43. static uint128_t bluetooth_base_uuid = {
  44. .data = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
  45. 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }
  46. };
  47. #define SDP_MAX_ATTR_LEN 65535
  48. /* match MTU used by RFCOMM */
  49. #define SDP_LARGE_L2CAP_MTU 1013
  50. static sdp_data_t *sdp_copy_seq(sdp_data_t *data);
  51. static int sdp_attr_add_new_with_length(sdp_record_t *rec,
  52. uint16_t attr, uint8_t dtd, const void *value, uint32_t len);
  53. static int sdp_gen_buffer(sdp_buf_t *buf, sdp_data_t *d);
  54. /* Message structure. */
  55. struct tupla {
  56. int index;
  57. char *str;
  58. };
  59. static struct tupla Protocol[] = {
  60. { SDP_UUID, "SDP" },
  61. { UDP_UUID, "UDP" },
  62. { RFCOMM_UUID, "RFCOMM" },
  63. { TCP_UUID, "TCP" },
  64. { TCS_BIN_UUID, "TCS-BIN" },
  65. { TCS_AT_UUID, "TCS-AT" },
  66. { OBEX_UUID, "OBEX" },
  67. { IP_UUID, "IP" },
  68. { FTP_UUID, "FTP" },
  69. { HTTP_UUID, "HTTP" },
  70. { WSP_UUID, "WSP" },
  71. { BNEP_UUID, "BNEP" },
  72. { UPNP_UUID, "UPNP" },
  73. { HIDP_UUID, "HIDP" },
  74. { HCRP_CTRL_UUID, "HCRP-Ctrl" },
  75. { HCRP_DATA_UUID, "HCRP-Data" },
  76. { HCRP_NOTE_UUID, "HCRP-Notify" },
  77. { AVCTP_UUID, "AVCTP" },
  78. { AVDTP_UUID, "AVDTP" },
  79. { CMTP_UUID, "CMTP" },
  80. { UDI_UUID, "UDI" },
  81. { MCAP_CTRL_UUID, "MCAP-Ctrl" },
  82. { MCAP_DATA_UUID, "MCAP-Data" },
  83. { L2CAP_UUID, "L2CAP" },
  84. { ATT_UUID, "ATT" },
  85. { 0 }
  86. };
  87. static struct tupla ServiceClass[] = {
  88. { SDP_SERVER_SVCLASS_ID, "SDP Server" },
  89. { BROWSE_GRP_DESC_SVCLASS_ID, "Browse Group Descriptor" },
  90. { PUBLIC_BROWSE_GROUP, "Public Browse Group" },
  91. { SERIAL_PORT_SVCLASS_ID, "Serial Port" },
  92. { LAN_ACCESS_SVCLASS_ID, "LAN Access Using PPP" },
  93. { DIALUP_NET_SVCLASS_ID, "Dialup Networking" },
  94. { IRMC_SYNC_SVCLASS_ID, "IrMC Sync" },
  95. { OBEX_OBJPUSH_SVCLASS_ID, "OBEX Object Push" },
  96. { OBEX_FILETRANS_SVCLASS_ID, "OBEX File Transfer" },
  97. { IRMC_SYNC_CMD_SVCLASS_ID, "IrMC Sync Command" },
  98. { HEADSET_SVCLASS_ID, "Headset" },
  99. { CORDLESS_TELEPHONY_SVCLASS_ID, "Cordless Telephony" },
  100. { AUDIO_SOURCE_SVCLASS_ID, "Audio Source" },
  101. { AUDIO_SINK_SVCLASS_ID, "Audio Sink" },
  102. { AV_REMOTE_TARGET_SVCLASS_ID, "AV Remote Target" },
  103. { ADVANCED_AUDIO_SVCLASS_ID, "Advanced Audio" },
  104. { AV_REMOTE_SVCLASS_ID, "AV Remote" },
  105. { AV_REMOTE_CONTROLLER_SVCLASS_ID, "AV Remote Controller" },
  106. { INTERCOM_SVCLASS_ID, "Intercom" },
  107. { FAX_SVCLASS_ID, "Fax" },
  108. { HEADSET_AGW_SVCLASS_ID, "Headset Audio Gateway" },
  109. { WAP_SVCLASS_ID, "WAP" },
  110. { WAP_CLIENT_SVCLASS_ID, "WAP Client" },
  111. { PANU_SVCLASS_ID, "PAN User" },
  112. { NAP_SVCLASS_ID, "Network Access Point" },
  113. { GN_SVCLASS_ID, "PAN Group Network" },
  114. { DIRECT_PRINTING_SVCLASS_ID, "Direct Printing" },
  115. { REFERENCE_PRINTING_SVCLASS_ID, "Reference Printing" },
  116. { IMAGING_SVCLASS_ID, "Imaging" },
  117. { IMAGING_RESPONDER_SVCLASS_ID, "Imaging Responder" },
  118. { IMAGING_ARCHIVE_SVCLASS_ID, "Imaging Automatic Archive" },
  119. { IMAGING_REFOBJS_SVCLASS_ID, "Imaging Referenced Objects" },
  120. { HANDSFREE_SVCLASS_ID, "Handsfree" },
  121. { HANDSFREE_AGW_SVCLASS_ID, "Handsfree Audio Gateway" },
  122. { DIRECT_PRT_REFOBJS_SVCLASS_ID, "Direct Printing Ref. Objects" },
  123. { REFLECTED_UI_SVCLASS_ID, "Reflected UI" },
  124. { BASIC_PRINTING_SVCLASS_ID, "Basic Printing" },
  125. { PRINTING_STATUS_SVCLASS_ID, "Printing Status" },
  126. { HID_SVCLASS_ID, "Human Interface Device" },
  127. { HCR_SVCLASS_ID, "Hardcopy Cable Replacement" },
  128. { HCR_PRINT_SVCLASS_ID, "HCR Print" },
  129. { HCR_SCAN_SVCLASS_ID, "HCR Scan" },
  130. { CIP_SVCLASS_ID, "Common ISDN Access" },
  131. { VIDEO_CONF_GW_SVCLASS_ID, "Video Conferencing Gateway" },
  132. { UDI_MT_SVCLASS_ID, "UDI MT" },
  133. { UDI_TA_SVCLASS_ID, "UDI TA" },
  134. { AV_SVCLASS_ID, "Audio/Video" },
  135. { SAP_SVCLASS_ID, "SIM Access" },
  136. { PBAP_PCE_SVCLASS_ID, "Phonebook Access - PCE" },
  137. { PBAP_PSE_SVCLASS_ID, "Phonebook Access - PSE" },
  138. { PBAP_SVCLASS_ID, "Phonebook Access" },
  139. { MAP_MSE_SVCLASS_ID, "Message Access - MAS" },
  140. { MAP_MCE_SVCLASS_ID, "Message Access - MNS" },
  141. { MAP_SVCLASS_ID, "Message Access" },
  142. { PNP_INFO_SVCLASS_ID, "PnP Information" },
  143. { GENERIC_NETWORKING_SVCLASS_ID, "Generic Networking" },
  144. { GENERIC_FILETRANS_SVCLASS_ID, "Generic File Transfer" },
  145. { GENERIC_AUDIO_SVCLASS_ID, "Generic Audio" },
  146. { GENERIC_TELEPHONY_SVCLASS_ID, "Generic Telephony" },
  147. { UPNP_SVCLASS_ID, "UPnP" },
  148. { UPNP_IP_SVCLASS_ID, "UPnP IP" },
  149. { UPNP_PAN_SVCLASS_ID, "UPnP PAN" },
  150. { UPNP_LAP_SVCLASS_ID, "UPnP LAP" },
  151. { UPNP_L2CAP_SVCLASS_ID, "UPnP L2CAP" },
  152. { VIDEO_SOURCE_SVCLASS_ID, "Video Source" },
  153. { VIDEO_SINK_SVCLASS_ID, "Video Sink" },
  154. { VIDEO_DISTRIBUTION_SVCLASS_ID, "Video Distribution" },
  155. { HDP_SVCLASS_ID, "HDP" },
  156. { HDP_SOURCE_SVCLASS_ID, "HDP Source" },
  157. { HDP_SINK_SVCLASS_ID, "HDP Sink" },
  158. { GENERIC_ACCESS_SVCLASS_ID, "Generic Access" },
  159. { GENERIC_ATTRIB_SVCLASS_ID, "Generic Attribute" },
  160. { APPLE_AGENT_SVCLASS_ID, "Apple Agent" },
  161. { 0 }
  162. };
  163. #define Profile ServiceClass
  164. static char *string_lookup(struct tupla *pt0, int index)
  165. {
  166. struct tupla *pt;
  167. for (pt = pt0; pt->index; pt++)
  168. if (pt->index == index)
  169. return pt->str;
  170. return "";
  171. }
  172. static char *string_lookup_uuid(struct tupla *pt0, const uuid_t *uuid)
  173. {
  174. uuid_t tmp_uuid;
  175. memcpy(&tmp_uuid, uuid, sizeof(tmp_uuid));
  176. if (sdp_uuid128_to_uuid(&tmp_uuid)) {
  177. switch (tmp_uuid.type) {
  178. case SDP_UUID16:
  179. return string_lookup(pt0, tmp_uuid.value.uuid16);
  180. case SDP_UUID32:
  181. return string_lookup(pt0, tmp_uuid.value.uuid32);
  182. }
  183. }
  184. return "";
  185. }
  186. /*
  187. * Prints into a string the Protocol UUID
  188. * coping a maximum of n characters.
  189. */
  190. static int uuid2str(struct tupla *message, const uuid_t *uuid, char *str, size_t n)
  191. {
  192. char *str2;
  193. if (!uuid) {
  194. snprintf(str, n, "NULL");
  195. return -2;
  196. }
  197. switch (uuid->type) {
  198. case SDP_UUID16:
  199. str2 = string_lookup(message, uuid->value.uuid16);
  200. snprintf(str, n, "%s", str2);
  201. break;
  202. case SDP_UUID32:
  203. str2 = string_lookup(message, uuid->value.uuid32);
  204. snprintf(str, n, "%s", str2);
  205. break;
  206. case SDP_UUID128:
  207. str2 = string_lookup_uuid(message, uuid);
  208. snprintf(str, n, "%s", str2);
  209. break;
  210. default:
  211. snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);
  212. return -1;
  213. }
  214. return 0;
  215. }
  216. int sdp_proto_uuid2strn(const uuid_t *uuid, char *str, size_t n)
  217. {
  218. return uuid2str(Protocol, uuid, str, n);
  219. }
  220. int sdp_svclass_uuid2strn(const uuid_t *uuid, char *str, size_t n)
  221. {
  222. return uuid2str(ServiceClass, uuid, str, n);
  223. }
  224. int sdp_profile_uuid2strn(const uuid_t *uuid, char *str, size_t n)
  225. {
  226. return uuid2str(Profile, uuid, str, n);
  227. }
  228. /*
  229. * convert the UUID to string, copying a maximum of n characters.
  230. */
  231. int sdp_uuid2strn(const uuid_t *uuid, char *str, size_t n)
  232. {
  233. if (!uuid) {
  234. snprintf(str, n, "NULL");
  235. return -2;
  236. }
  237. switch (uuid->type) {
  238. case SDP_UUID16:
  239. snprintf(str, n, "%.4x", uuid->value.uuid16);
  240. break;
  241. case SDP_UUID32:
  242. snprintf(str, n, "%.8x", uuid->value.uuid32);
  243. break;
  244. case SDP_UUID128:{
  245. unsigned int data0;
  246. unsigned short data1;
  247. unsigned short data2;
  248. unsigned short data3;
  249. unsigned int data4;
  250. unsigned short data5;
  251. memcpy(&data0, &uuid->value.uuid128.data[0], 4);
  252. memcpy(&data1, &uuid->value.uuid128.data[4], 2);
  253. memcpy(&data2, &uuid->value.uuid128.data[6], 2);
  254. memcpy(&data3, &uuid->value.uuid128.data[8], 2);
  255. memcpy(&data4, &uuid->value.uuid128.data[10], 4);
  256. memcpy(&data5, &uuid->value.uuid128.data[14], 2);
  257. snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
  258. ntohl(data0), ntohs(data1),
  259. ntohs(data2), ntohs(data3),
  260. ntohl(data4), ntohs(data5));
  261. }
  262. break;
  263. default:
  264. snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);
  265. return -1; /* Enum type of UUID not set */
  266. }
  267. return 0;
  268. }
  269. #ifdef SDP_DEBUG
  270. /*
  271. * Function prints the UUID in hex as per defined syntax -
  272. *
  273. * 4bytes-2bytes-2bytes-2bytes-6bytes
  274. *
  275. * There is some ugly code, including hardcoding, but
  276. * that is just the way it is converting 16 and 32 bit
  277. * UUIDs to 128 bit as defined in the SDP doc
  278. */
  279. void sdp_uuid_print(const uuid_t *uuid)
  280. {
  281. if (uuid == NULL) {
  282. SDPERR("Null passed to print UUID");
  283. return;
  284. }
  285. if (uuid->type == SDP_UUID16) {
  286. SDPDBG(" uint16_t : 0x%.4x", uuid->value.uuid16);
  287. } else if (uuid->type == SDP_UUID32) {
  288. SDPDBG(" uint32_t : 0x%.8x", uuid->value.uuid32);
  289. } else if (uuid->type == SDP_UUID128) {
  290. unsigned int data0;
  291. unsigned short data1;
  292. unsigned short data2;
  293. unsigned short data3;
  294. unsigned int data4;
  295. unsigned short data5;
  296. memcpy(&data0, &uuid->value.uuid128.data[0], 4);
  297. memcpy(&data1, &uuid->value.uuid128.data[4], 2);
  298. memcpy(&data2, &uuid->value.uuid128.data[6], 2);
  299. memcpy(&data3, &uuid->value.uuid128.data[8], 2);
  300. memcpy(&data4, &uuid->value.uuid128.data[10], 4);
  301. memcpy(&data5, &uuid->value.uuid128.data[14], 2);
  302. SDPDBG(" uint128_t : 0x%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
  303. ntohl(data0), ntohs(data1), ntohs(data2),
  304. ntohs(data3), ntohl(data4), ntohs(data5));
  305. } else
  306. SDPERR("Enum type of UUID not set");
  307. }
  308. #endif
  309. sdp_data_t *sdp_data_alloc_with_length(uint8_t dtd, const void *value,
  310. uint32_t length)
  311. {
  312. sdp_data_t *seq;
  313. sdp_data_t *d = bt_malloc0(sizeof(sdp_data_t));
  314. if (!d)
  315. return NULL;
  316. d->dtd = dtd;
  317. d->unitSize = sizeof(uint8_t);
  318. switch (dtd) {
  319. case SDP_DATA_NIL:
  320. break;
  321. case SDP_UINT8:
  322. d->val.uint8 = *(uint8_t *) value;
  323. d->unitSize += sizeof(uint8_t);
  324. break;
  325. case SDP_INT8:
  326. case SDP_BOOL:
  327. d->val.int8 = *(int8_t *) value;
  328. d->unitSize += sizeof(int8_t);
  329. break;
  330. case SDP_UINT16:
  331. d->val.uint16 = bt_get_unaligned((uint16_t *) value);
  332. d->unitSize += sizeof(uint16_t);
  333. break;
  334. case SDP_INT16:
  335. d->val.int16 = bt_get_unaligned((int16_t *) value);
  336. d->unitSize += sizeof(int16_t);
  337. break;
  338. case SDP_UINT32:
  339. d->val.uint32 = bt_get_unaligned((uint32_t *) value);
  340. d->unitSize += sizeof(uint32_t);
  341. break;
  342. case SDP_INT32:
  343. d->val.int32 = bt_get_unaligned((int32_t *) value);
  344. d->unitSize += sizeof(int32_t);
  345. break;
  346. case SDP_INT64:
  347. d->val.int64 = bt_get_unaligned((int64_t *) value);
  348. d->unitSize += sizeof(int64_t);
  349. break;
  350. case SDP_UINT64:
  351. d->val.uint64 = bt_get_unaligned((uint64_t *) value);
  352. d->unitSize += sizeof(uint64_t);
  353. break;
  354. case SDP_UINT128:
  355. memcpy(&d->val.uint128.data, value, sizeof(uint128_t));
  356. d->unitSize += sizeof(uint128_t);
  357. break;
  358. case SDP_INT128:
  359. memcpy(&d->val.int128.data, value, sizeof(uint128_t));
  360. d->unitSize += sizeof(uint128_t);
  361. break;
  362. case SDP_UUID16:
  363. sdp_uuid16_create(&d->val.uuid, bt_get_unaligned((uint16_t *) value));
  364. d->unitSize += sizeof(uint16_t);
  365. break;
  366. case SDP_UUID32:
  367. sdp_uuid32_create(&d->val.uuid, bt_get_unaligned((uint32_t *) value));
  368. d->unitSize += sizeof(uint32_t);
  369. break;
  370. case SDP_UUID128:
  371. sdp_uuid128_create(&d->val.uuid, value);
  372. d->unitSize += sizeof(uint128_t);
  373. break;
  374. case SDP_URL_STR8:
  375. case SDP_URL_STR16:
  376. case SDP_TEXT_STR8:
  377. case SDP_TEXT_STR16:
  378. if (!value) {
  379. free(d);
  380. return NULL;
  381. }
  382. d->unitSize += length;
  383. if (length <= USHRT_MAX) {
  384. d->val.str = malloc(length);
  385. if (!d->val.str) {
  386. free(d);
  387. return NULL;
  388. }
  389. memcpy(d->val.str, value, length);
  390. } else {
  391. SDPERR("Strings of size > USHRT_MAX not supported");
  392. free(d);
  393. d = NULL;
  394. }
  395. break;
  396. case SDP_URL_STR32:
  397. case SDP_TEXT_STR32:
  398. SDPERR("Strings of size > USHRT_MAX not supported");
  399. break;
  400. case SDP_ALT8:
  401. case SDP_ALT16:
  402. case SDP_ALT32:
  403. case SDP_SEQ8:
  404. case SDP_SEQ16:
  405. case SDP_SEQ32:
  406. if (dtd == SDP_ALT8 || dtd == SDP_SEQ8)
  407. d->unitSize += sizeof(uint8_t);
  408. else if (dtd == SDP_ALT16 || dtd == SDP_SEQ16)
  409. d->unitSize += sizeof(uint16_t);
  410. else if (dtd == SDP_ALT32 || dtd == SDP_SEQ32)
  411. d->unitSize += sizeof(uint32_t);
  412. seq = (sdp_data_t *)value;
  413. d->val.dataseq = seq;
  414. for (; seq; seq = seq->next)
  415. d->unitSize += seq->unitSize;
  416. break;
  417. default:
  418. free(d);
  419. d = NULL;
  420. }
  421. return d;
  422. }
  423. sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value)
  424. {
  425. uint32_t length;
  426. switch (dtd) {
  427. case SDP_URL_STR8:
  428. case SDP_URL_STR16:
  429. case SDP_TEXT_STR8:
  430. case SDP_TEXT_STR16:
  431. if (!value)
  432. return NULL;
  433. length = strlen((char *) value);
  434. break;
  435. default:
  436. length = 0;
  437. break;
  438. }
  439. return sdp_data_alloc_with_length(dtd, value, length);
  440. }
  441. sdp_data_t *sdp_seq_append(sdp_data_t *seq, sdp_data_t *d)
  442. {
  443. if (seq) {
  444. sdp_data_t *p;
  445. for (p = seq; p->next; p = p->next);
  446. p->next = d;
  447. } else
  448. seq = d;
  449. d->next = NULL;
  450. return seq;
  451. }
  452. sdp_data_t *sdp_seq_alloc_with_length(void **dtds, void **values, int *length,
  453. int len)
  454. {
  455. sdp_data_t *curr = NULL, *seq = NULL;
  456. int i;
  457. for (i = 0; i < len; i++) {
  458. sdp_data_t *data;
  459. int8_t dtd = *(uint8_t *) dtds[i];
  460. if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32)
  461. data = (sdp_data_t *) values[i];
  462. else
  463. data = sdp_data_alloc_with_length(dtd, values[i], length[i]);
  464. if (!data)
  465. return NULL;
  466. if (curr)
  467. curr->next = data;
  468. else
  469. seq = data;
  470. curr = data;
  471. }
  472. return sdp_data_alloc(SDP_SEQ8, seq);
  473. }
  474. sdp_data_t *sdp_seq_alloc(void **dtds, void **values, int len)
  475. {
  476. sdp_data_t *curr = NULL, *seq = NULL;
  477. int i;
  478. for (i = 0; i < len; i++) {
  479. sdp_data_t *data;
  480. uint8_t dtd = *(uint8_t *) dtds[i];
  481. if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32)
  482. data = (sdp_data_t *) values[i];
  483. else
  484. data = sdp_data_alloc(dtd, values[i]);
  485. if (!data)
  486. return NULL;
  487. if (curr)
  488. curr->next = data;
  489. else
  490. seq = data;
  491. curr = data;
  492. }
  493. return sdp_data_alloc(SDP_SEQ8, seq);
  494. }
  495. static void extract_svclass_uuid(sdp_data_t *data, uuid_t *uuid)
  496. {
  497. sdp_data_t *d;
  498. if (!data || !SDP_IS_SEQ(data->dtd))
  499. return;
  500. d = data->val.dataseq;
  501. if (!d)
  502. return;
  503. if (d->dtd < SDP_UUID16 || d->dtd > SDP_UUID128)
  504. return;
  505. *uuid = d->val.uuid;
  506. }
  507. int sdp_attr_add(sdp_record_t *rec, uint16_t attr, sdp_data_t *d)
  508. {
  509. sdp_data_t *p = sdp_data_get(rec, attr);
  510. if (p)
  511. return -1;
  512. d->attrId = attr;
  513. rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func);
  514. if (attr == SDP_ATTR_SVCLASS_ID_LIST)
  515. extract_svclass_uuid(d, &rec->svclass);
  516. return 0;
  517. }
  518. void sdp_attr_remove(sdp_record_t *rec, uint16_t attr)
  519. {
  520. sdp_data_t *d = sdp_data_get(rec, attr);
  521. if (d)
  522. rec->attrlist = sdp_list_remove(rec->attrlist, d);
  523. if (attr == SDP_ATTR_SVCLASS_ID_LIST)
  524. memset(&rec->svclass, 0, sizeof(rec->svclass));
  525. }
  526. void sdp_set_seq_len(uint8_t *ptr, uint32_t length)
  527. {
  528. uint8_t dtd = *ptr++;
  529. switch (dtd) {
  530. case SDP_SEQ8:
  531. case SDP_ALT8:
  532. case SDP_TEXT_STR8:
  533. case SDP_URL_STR8:
  534. *ptr = (uint8_t) length;
  535. break;
  536. case SDP_SEQ16:
  537. case SDP_ALT16:
  538. case SDP_TEXT_STR16:
  539. case SDP_URL_STR16:
  540. bt_put_be16(length, ptr);
  541. break;
  542. case SDP_SEQ32:
  543. case SDP_ALT32:
  544. case SDP_TEXT_STR32:
  545. case SDP_URL_STR32:
  546. bt_put_be32(length, ptr);
  547. break;
  548. }
  549. }
  550. static int sdp_get_data_type_size(uint8_t dtd)
  551. {
  552. int size = sizeof(uint8_t);
  553. switch (dtd) {
  554. case SDP_SEQ8:
  555. case SDP_TEXT_STR8:
  556. case SDP_URL_STR8:
  557. case SDP_ALT8:
  558. size += sizeof(uint8_t);
  559. break;
  560. case SDP_SEQ16:
  561. case SDP_TEXT_STR16:
  562. case SDP_URL_STR16:
  563. case SDP_ALT16:
  564. size += sizeof(uint16_t);
  565. break;
  566. case SDP_SEQ32:
  567. case SDP_TEXT_STR32:
  568. case SDP_URL_STR32:
  569. case SDP_ALT32:
  570. size += sizeof(uint32_t);
  571. break;
  572. }
  573. return size;
  574. }
  575. void sdp_set_attrid(sdp_buf_t *buf, uint16_t attr)
  576. {
  577. uint8_t *p = buf->data;
  578. /* data type for attr */
  579. *p++ = SDP_UINT16;
  580. buf->data_size = sizeof(uint8_t);
  581. bt_put_be16(attr, p);
  582. buf->data_size += sizeof(uint16_t);
  583. }
  584. static int get_data_size(sdp_buf_t *buf, sdp_data_t *sdpdata)
  585. {
  586. sdp_data_t *d;
  587. int n = 0;
  588. for (d = sdpdata->val.dataseq; d; d = d->next) {
  589. if (buf->data)
  590. n += sdp_gen_pdu(buf, d);
  591. else
  592. n += sdp_gen_buffer(buf, d);
  593. }
  594. return n;
  595. }
  596. static int sdp_get_data_size(sdp_buf_t *buf, sdp_data_t *d)
  597. {
  598. uint32_t data_size = 0;
  599. uint8_t dtd = d->dtd;
  600. switch (dtd) {
  601. case SDP_DATA_NIL:
  602. break;
  603. case SDP_UINT8:
  604. data_size = sizeof(uint8_t);
  605. break;
  606. case SDP_UINT16:
  607. data_size = sizeof(uint16_t);
  608. break;
  609. case SDP_UINT32:
  610. data_size = sizeof(uint32_t);
  611. break;
  612. case SDP_UINT64:
  613. data_size = sizeof(uint64_t);
  614. break;
  615. case SDP_UINT128:
  616. data_size = sizeof(uint128_t);
  617. break;
  618. case SDP_INT8:
  619. case SDP_BOOL:
  620. data_size = sizeof(int8_t);
  621. break;
  622. case SDP_INT16:
  623. data_size = sizeof(int16_t);
  624. break;
  625. case SDP_INT32:
  626. data_size = sizeof(int32_t);
  627. break;
  628. case SDP_INT64:
  629. data_size = sizeof(int64_t);
  630. break;
  631. case SDP_INT128:
  632. data_size = sizeof(uint128_t);
  633. break;
  634. case SDP_TEXT_STR8:
  635. case SDP_TEXT_STR16:
  636. case SDP_TEXT_STR32:
  637. case SDP_URL_STR8:
  638. case SDP_URL_STR16:
  639. case SDP_URL_STR32:
  640. data_size = d->unitSize - sizeof(uint8_t);
  641. break;
  642. case SDP_SEQ8:
  643. case SDP_SEQ16:
  644. case SDP_SEQ32:
  645. data_size = get_data_size(buf, d);
  646. break;
  647. case SDP_ALT8:
  648. case SDP_ALT16:
  649. case SDP_ALT32:
  650. data_size = get_data_size(buf, d);
  651. break;
  652. case SDP_UUID16:
  653. data_size = sizeof(uint16_t);
  654. break;
  655. case SDP_UUID32:
  656. data_size = sizeof(uint32_t);
  657. break;
  658. case SDP_UUID128:
  659. data_size = sizeof(uint128_t);
  660. break;
  661. default:
  662. break;
  663. }
  664. return data_size;
  665. }
  666. static int sdp_gen_buffer(sdp_buf_t *buf, sdp_data_t *d)
  667. {
  668. int orig = buf->buf_size;
  669. if (buf->buf_size == 0 && d->dtd == 0) {
  670. /* create initial sequence */
  671. buf->buf_size += sizeof(uint8_t);
  672. /* reserve space for sequence size */
  673. buf->buf_size += sizeof(uint8_t);
  674. }
  675. /* attribute length */
  676. buf->buf_size += sizeof(uint8_t) + sizeof(uint16_t);
  677. buf->buf_size += sdp_get_data_type_size(d->dtd);
  678. buf->buf_size += sdp_get_data_size(buf, d);
  679. if (buf->buf_size > UCHAR_MAX && d->dtd == SDP_SEQ8)
  680. buf->buf_size += sizeof(uint8_t);
  681. return buf->buf_size - orig;
  682. }
  683. int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d)
  684. {
  685. uint32_t pdu_size, data_size;
  686. unsigned char *src = NULL, is_seq = 0, is_alt = 0;
  687. uint16_t u16;
  688. uint32_t u32;
  689. uint64_t u64;
  690. uint128_t u128;
  691. uint8_t *seqp = buf->data + buf->data_size;
  692. uint32_t orig_data_size = buf->data_size;
  693. recalculate:
  694. pdu_size = sdp_get_data_type_size(d->dtd);
  695. buf->data_size += pdu_size;
  696. data_size = sdp_get_data_size(buf, d);
  697. if (data_size > UCHAR_MAX && d->dtd == SDP_SEQ8) {
  698. buf->data_size = orig_data_size;
  699. d->dtd = SDP_SEQ16;
  700. goto recalculate;
  701. }
  702. *seqp = d->dtd;
  703. switch (d->dtd) {
  704. case SDP_DATA_NIL:
  705. break;
  706. case SDP_UINT8:
  707. src = &d->val.uint8;
  708. break;
  709. case SDP_UINT16:
  710. u16 = htons(d->val.uint16);
  711. src = (unsigned char *) &u16;
  712. break;
  713. case SDP_UINT32:
  714. u32 = htonl(d->val.uint32);
  715. src = (unsigned char *) &u32;
  716. break;
  717. case SDP_UINT64:
  718. u64 = hton64(d->val.uint64);
  719. src = (unsigned char *) &u64;
  720. break;
  721. case SDP_UINT128:
  722. hton128(&d->val.uint128, &u128);
  723. src = (unsigned char *) &u128;
  724. break;
  725. case SDP_INT8:
  726. case SDP_BOOL:
  727. src = (unsigned char *) &d->val.int8;
  728. break;
  729. case SDP_INT16:
  730. u16 = htons(d->val.int16);
  731. src = (unsigned char *) &u16;
  732. break;
  733. case SDP_INT32:
  734. u32 = htonl(d->val.int32);
  735. src = (unsigned char *) &u32;
  736. break;
  737. case SDP_INT64:
  738. u64 = hton64(d->val.int64);
  739. src = (unsigned char *) &u64;
  740. break;
  741. case SDP_INT128:
  742. hton128(&d->val.int128, &u128);
  743. src = (unsigned char *) &u128;
  744. break;
  745. case SDP_TEXT_STR8:
  746. case SDP_TEXT_STR16:
  747. case SDP_TEXT_STR32:
  748. case SDP_URL_STR8:
  749. case SDP_URL_STR16:
  750. case SDP_URL_STR32:
  751. src = (unsigned char *) d->val.str;
  752. sdp_set_seq_len(seqp, data_size);
  753. break;
  754. case SDP_SEQ8:
  755. case SDP_SEQ16:
  756. case SDP_SEQ32:
  757. is_seq = 1;
  758. sdp_set_seq_len(seqp, data_size);
  759. break;
  760. case SDP_ALT8:
  761. case SDP_ALT16:
  762. case SDP_ALT32:
  763. is_alt = 1;
  764. sdp_set_seq_len(seqp, data_size);
  765. break;
  766. case SDP_UUID16:
  767. u16 = htons(d->val.uuid.value.uuid16);
  768. src = (unsigned char *) &u16;
  769. break;
  770. case SDP_UUID32:
  771. u32 = htonl(d->val.uuid.value.uuid32);
  772. src = (unsigned char *) &u32;
  773. break;
  774. case SDP_UUID128:
  775. src = (unsigned char *) &d->val.uuid.value.uuid128;
  776. break;
  777. default:
  778. break;
  779. }
  780. if (!is_seq && !is_alt) {
  781. if (src && buf->buf_size >= buf->data_size + data_size) {
  782. memcpy(buf->data + buf->data_size, src, data_size);
  783. buf->data_size += data_size;
  784. } else if (d->dtd != SDP_DATA_NIL) {
  785. SDPDBG("Gen PDU : Can't copy from invalid source or dest");
  786. }
  787. }
  788. pdu_size += data_size;
  789. return pdu_size;
  790. }
  791. static void sdp_attr_pdu(void *value, void *udata)
  792. {
  793. sdp_append_to_pdu((sdp_buf_t *)udata, (sdp_data_t *)value);
  794. }
  795. static void sdp_attr_size(void *value, void *udata)
  796. {
  797. sdp_gen_buffer((sdp_buf_t *)udata, (sdp_data_t *)value);
  798. }
  799. int sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *buf)
  800. {
  801. memset(buf, 0, sizeof(sdp_buf_t));
  802. sdp_list_foreach(rec->attrlist, sdp_attr_size, buf);
  803. buf->data = bt_malloc0(buf->buf_size);
  804. if (!buf->data)
  805. return -ENOMEM;
  806. buf->data_size = 0;
  807. sdp_list_foreach(rec->attrlist, sdp_attr_pdu, buf);
  808. return 0;
  809. }
  810. void sdp_attr_replace(sdp_record_t *rec, uint16_t attr, sdp_data_t *d)
  811. {
  812. sdp_data_t *p;
  813. if (!rec)
  814. return;
  815. p = sdp_data_get(rec, attr);
  816. if (p) {
  817. rec->attrlist = sdp_list_remove(rec->attrlist, p);
  818. sdp_data_free(p);
  819. }
  820. d->attrId = attr;
  821. rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func);
  822. if (attr == SDP_ATTR_SVCLASS_ID_LIST)
  823. extract_svclass_uuid(d, &rec->svclass);
  824. }
  825. int sdp_attrid_comp_func(const void *key1, const void *key2)
  826. {
  827. const sdp_data_t *d1 = (const sdp_data_t *)key1;
  828. const sdp_data_t *d2 = (const sdp_data_t *)key2;
  829. if (d1 && d2)
  830. return d1->attrId - d2->attrId;
  831. return 0;
  832. }
  833. static void data_seq_free(sdp_data_t *seq)
  834. {
  835. sdp_data_t *d = seq->val.dataseq;
  836. while (d) {
  837. sdp_data_t *next = d->next;
  838. sdp_data_free(d);
  839. d = next;
  840. }
  841. }
  842. void sdp_data_free(sdp_data_t *d)
  843. {
  844. switch (d->dtd) {
  845. case SDP_SEQ8:
  846. case SDP_SEQ16:
  847. case SDP_SEQ32:
  848. data_seq_free(d);
  849. break;
  850. case SDP_URL_STR8:
  851. case SDP_URL_STR16:
  852. case SDP_URL_STR32:
  853. case SDP_TEXT_STR8:
  854. case SDP_TEXT_STR16:
  855. case SDP_TEXT_STR32:
  856. free(d->val.str);
  857. break;
  858. }
  859. free(d);
  860. }
  861. int sdp_uuid_extract(const uint8_t *p, int bufsize, uuid_t *uuid, int *scanned)
  862. {
  863. uint8_t type;
  864. if (bufsize < (int) sizeof(uint8_t)) {
  865. SDPERR("Unexpected end of packet");
  866. return -1;
  867. }
  868. type = *(const uint8_t *) p;
  869. if (!SDP_IS_UUID(type)) {
  870. SDPERR("Unknown data type : %d expecting a svc UUID", type);
  871. return -1;
  872. }
  873. p += sizeof(uint8_t);
  874. *scanned += sizeof(uint8_t);
  875. bufsize -= sizeof(uint8_t);
  876. if (type == SDP_UUID16) {
  877. if (bufsize < (int) sizeof(uint16_t)) {
  878. SDPERR("Not enough room for 16-bit UUID");
  879. return -1;
  880. }
  881. sdp_uuid16_create(uuid, bt_get_be16(p));
  882. *scanned += sizeof(uint16_t);
  883. } else if (type == SDP_UUID32) {
  884. if (bufsize < (int) sizeof(uint32_t)) {
  885. SDPERR("Not enough room for 32-bit UUID");
  886. return -1;
  887. }
  888. sdp_uuid32_create(uuid, bt_get_be32(p));
  889. *scanned += sizeof(uint32_t);
  890. } else {
  891. if (bufsize < (int) sizeof(uint128_t)) {
  892. SDPERR("Not enough room for 128-bit UUID");
  893. return -1;
  894. }
  895. sdp_uuid128_create(uuid, p);
  896. *scanned += sizeof(uint128_t);
  897. }
  898. return 0;
  899. }
  900. static sdp_data_t *extract_int(const void *p, int bufsize, int *len)
  901. {
  902. sdp_data_t *d;
  903. if (bufsize < (int) sizeof(uint8_t)) {
  904. SDPERR("Unexpected end of packet");
  905. return NULL;
  906. }
  907. d = bt_malloc0(sizeof(sdp_data_t));
  908. if (!d)
  909. return NULL;
  910. SDPDBG("Extracting integer");
  911. d->dtd = *(uint8_t *) p;
  912. p += sizeof(uint8_t);
  913. *len += sizeof(uint8_t);
  914. bufsize -= sizeof(uint8_t);
  915. switch (d->dtd) {
  916. case SDP_DATA_NIL:
  917. break;
  918. case SDP_BOOL:
  919. case SDP_INT8:
  920. case SDP_UINT8:
  921. if (bufsize < (int) sizeof(uint8_t)) {
  922. SDPERR("Unexpected end of packet");
  923. free(d);
  924. return NULL;
  925. }
  926. *len += sizeof(uint8_t);
  927. d->val.uint8 = *(uint8_t *) p;
  928. break;
  929. case SDP_INT16:
  930. case SDP_UINT16:
  931. if (bufsize < (int) sizeof(uint16_t)) {
  932. SDPERR("Unexpected end of packet");
  933. free(d);
  934. return NULL;
  935. }
  936. *len += sizeof(uint16_t);
  937. d->val.uint16 = bt_get_be16(p);
  938. break;
  939. case SDP_INT32:
  940. case SDP_UINT32:
  941. if (bufsize < (int) sizeof(uint32_t)) {
  942. SDPERR("Unexpected end of packet");
  943. free(d);
  944. return NULL;
  945. }
  946. *len += sizeof(uint32_t);
  947. d->val.uint32 = bt_get_be32(p);
  948. break;
  949. case SDP_INT64:
  950. case SDP_UINT64:
  951. if (bufsize < (int) sizeof(uint64_t)) {
  952. SDPERR("Unexpected end of packet");
  953. free(d);
  954. return NULL;
  955. }
  956. *len += sizeof(uint64_t);
  957. d->val.uint64 = bt_get_be64(p);
  958. break;
  959. case SDP_INT128:
  960. case SDP_UINT128:
  961. if (bufsize < (int) sizeof(uint128_t)) {
  962. SDPERR("Unexpected end of packet");
  963. free(d);
  964. return NULL;
  965. }
  966. *len += sizeof(uint128_t);
  967. ntoh128((uint128_t *) p, &d->val.uint128);
  968. break;
  969. default:
  970. free(d);
  971. d = NULL;
  972. }
  973. return d;
  974. }
  975. static sdp_data_t *extract_uuid(const uint8_t *p, int bufsize, int *len,
  976. sdp_record_t *rec)
  977. {
  978. sdp_data_t *d = bt_malloc0(sizeof(sdp_data_t));
  979. if (!d)
  980. return NULL;
  981. SDPDBG("Extracting UUID");
  982. if (sdp_uuid_extract(p, bufsize, &d->val.uuid, len) < 0) {
  983. free(d);
  984. return NULL;
  985. }
  986. d->dtd = *p;
  987. if (rec)
  988. sdp_pattern_add_uuid(rec, &d->val.uuid);
  989. return d;
  990. }
  991. /*
  992. * Extract strings from the PDU (could be service description and similar info)
  993. */
  994. static sdp_data_t *extract_str(const void *p, int bufsize, int *len)
  995. {
  996. char *s;
  997. int n;
  998. sdp_data_t *d;
  999. if (bufsize < (int) sizeof(uint8_t)) {
  1000. SDPERR("Unexpected end of packet");
  1001. return NULL;
  1002. }
  1003. d = bt_malloc0(sizeof(sdp_data_t));
  1004. if (!d)
  1005. return NULL;
  1006. d->dtd = *(uint8_t *) p;
  1007. p += sizeof(uint8_t);
  1008. *len += sizeof(uint8_t);
  1009. bufsize -= sizeof(uint8_t);
  1010. switch (d->dtd) {
  1011. case SDP_TEXT_STR8:
  1012. case SDP_URL_STR8:
  1013. if (bufsize < (int) sizeof(uint8_t)) {
  1014. SDPERR("Unexpected end of packet");
  1015. free(d);
  1016. return NULL;
  1017. }
  1018. n = *(uint8_t *) p;
  1019. p += sizeof(uint8_t);
  1020. *len += sizeof(uint8_t);
  1021. bufsize -= sizeof(uint8_t);
  1022. break;
  1023. case SDP_TEXT_STR16:
  1024. case SDP_URL_STR16:
  1025. if (bufsize < (int) sizeof(uint16_t)) {
  1026. SDPERR("Unexpected end of packet");
  1027. free(d);
  1028. return NULL;
  1029. }
  1030. n = bt_get_be16(p);
  1031. p += sizeof(uint16_t);
  1032. *len += sizeof(uint16_t);
  1033. bufsize -= sizeof(uint16_t);
  1034. break;
  1035. default:
  1036. SDPERR("Sizeof text string > UINT16_MAX");
  1037. free(d);
  1038. return NULL;
  1039. }
  1040. if (bufsize < n) {
  1041. SDPERR("String too long to fit in packet");
  1042. free(d);
  1043. return NULL;
  1044. }
  1045. s = bt_malloc0(n + 1);
  1046. if (!s) {
  1047. SDPERR("Not enough memory for incoming string");
  1048. free(d);
  1049. return NULL;
  1050. }
  1051. memcpy(s, p, n);
  1052. *len += n;
  1053. SDPDBG("Len : %d", n);
  1054. SDPDBG("Str : %s", s);
  1055. d->val.str = s;
  1056. d->unitSize = n + sizeof(uint8_t);
  1057. return d;
  1058. }
  1059. /*
  1060. * Extract the sequence type and its length, and return offset into buf
  1061. * or 0 on failure.
  1062. */
  1063. int sdp_extract_seqtype(const uint8_t *buf, int bufsize, uint8_t *dtdp, int *size)
  1064. {
  1065. uint8_t dtd;
  1066. int scanned = sizeof(uint8_t);
  1067. if (bufsize < (int) sizeof(uint8_t)) {
  1068. SDPERR("Unexpected end of packet");
  1069. return 0;
  1070. }
  1071. dtd = *(uint8_t *) buf;
  1072. buf += sizeof(uint8_t);
  1073. bufsize -= sizeof(uint8_t);
  1074. *dtdp = dtd;
  1075. switch (dtd) {
  1076. case SDP_SEQ8:
  1077. case SDP_ALT8:
  1078. if (bufsize < (int) sizeof(uint8_t)) {
  1079. SDPERR("Unexpected end of packet");
  1080. return 0;
  1081. }
  1082. *size = *(uint8_t *) buf;
  1083. scanned += sizeof(uint8_t);
  1084. break;
  1085. case SDP_SEQ16:
  1086. case SDP_ALT16:
  1087. if (bufsize < (int) sizeof(uint16_t)) {
  1088. SDPERR("Unexpected end of packet");
  1089. return 0;
  1090. }
  1091. *size = bt_get_be16(buf);
  1092. scanned += sizeof(uint16_t);
  1093. break;
  1094. case SDP_SEQ32:
  1095. case SDP_ALT32:
  1096. if (bufsize < (int) sizeof(uint32_t)) {
  1097. SDPERR("Unexpected end of packet");
  1098. return 0;
  1099. }
  1100. *size = bt_get_be32(buf);
  1101. scanned += sizeof(uint32_t);
  1102. break;
  1103. default:
  1104. SDPERR("Unknown sequence type, aborting");
  1105. return 0;
  1106. }
  1107. return scanned;
  1108. }
  1109. static sdp_data_t *extract_seq(const void *p, int bufsize, int *len,
  1110. sdp_record_t *rec)
  1111. {
  1112. int seqlen, n = 0;
  1113. sdp_data_t *curr, *prev;
  1114. sdp_data_t *d = bt_malloc0(sizeof(sdp_data_t));
  1115. if (!d)
  1116. return NULL;
  1117. SDPDBG("Extracting SEQ");
  1118. *len = sdp_extract_seqtype(p, bufsize, &d->dtd, &seqlen);
  1119. SDPDBG("Sequence Type : 0x%x length : 0x%x", d->dtd, seqlen);
  1120. if (*len == 0)
  1121. return d;
  1122. if (*len > bufsize) {
  1123. SDPERR("Packet not big enough to hold sequence.");
  1124. free(d);
  1125. return NULL;
  1126. }
  1127. p += *len;
  1128. bufsize -= *len;
  1129. prev = NULL;
  1130. while (n < seqlen) {
  1131. int attrlen = 0;
  1132. curr = sdp_extract_attr(p, bufsize, &attrlen, rec);
  1133. if (curr == NULL)
  1134. break;
  1135. if (prev)
  1136. prev->next = curr;
  1137. else
  1138. d->val.dataseq = curr;
  1139. prev = curr;
  1140. p += attrlen;
  1141. n += attrlen;
  1142. bufsize -= attrlen;
  1143. SDPDBG("Extracted: %d SequenceLength: %d", n, seqlen);
  1144. }
  1145. *len += n;
  1146. return d;
  1147. }
  1148. sdp_data_t *sdp_extract_attr(const uint8_t *p, int bufsize, int *size,
  1149. sdp_record_t *rec)
  1150. {
  1151. sdp_data_t *elem;
  1152. int n = 0;
  1153. uint8_t dtd;
  1154. if (bufsize < (int) sizeof(uint8_t)) {
  1155. SDPERR("Unexpected end of packet");
  1156. return NULL;
  1157. }
  1158. dtd = *(const uint8_t *)p;
  1159. SDPDBG("extract_attr: dtd=0x%x", dtd);
  1160. switch (dtd) {
  1161. case SDP_DATA_NIL:
  1162. case SDP_BOOL:
  1163. case SDP_UINT8:
  1164. case SDP_UINT16:
  1165. case SDP_UINT32:
  1166. case SDP_UINT64:
  1167. case SDP_UINT128:
  1168. case SDP_INT8:
  1169. case SDP_INT16:
  1170. case SDP_INT32:
  1171. case SDP_INT64:
  1172. case SDP_INT128:
  1173. elem = extract_int(p, bufsize, &n);
  1174. break;
  1175. case SDP_UUID16:
  1176. case SDP_UUID32:
  1177. case SDP_UUID128:
  1178. elem = extract_uuid(p, bufsize, &n, rec);
  1179. break;
  1180. case SDP_TEXT_STR8:
  1181. case SDP_TEXT_STR16:
  1182. case SDP_TEXT_STR32:
  1183. case SDP_URL_STR8:
  1184. case SDP_URL_STR16:
  1185. case SDP_URL_STR32:
  1186. elem = extract_str(p, bufsize, &n);
  1187. break;
  1188. case SDP_SEQ8:
  1189. case SDP_SEQ16:
  1190. case SDP_SEQ32:
  1191. case SDP_ALT8:
  1192. case SDP_ALT16:
  1193. case SDP_ALT32:
  1194. elem = extract_seq(p, bufsize, &n, rec);
  1195. break;
  1196. default:
  1197. SDPERR("Unknown data descriptor : 0x%x terminating", dtd);
  1198. return NULL;
  1199. }
  1200. *size += n;
  1201. return elem;
  1202. }
  1203. #ifdef SDP_DEBUG
  1204. static void attr_print_func(void *value, void *userData)
  1205. {
  1206. sdp_data_t *d = (sdp_data_t *)value;
  1207. SDPDBG("=====================================");
  1208. SDPDBG("ATTRIBUTE IDENTIFIER : 0x%x", d->attrId);
  1209. SDPDBG("ATTRIBUTE VALUE PTR : %p", value);
  1210. if (d)
  1211. sdp_data_print(d);
  1212. else
  1213. SDPDBG("NULL value");
  1214. SDPDBG("=====================================");
  1215. }
  1216. void sdp_print_service_attr(sdp_list_t *svcAttrList)
  1217. {
  1218. SDPDBG("Printing service attr list %p", svcAttrList);
  1219. sdp_list_foreach(svcAttrList, attr_print_func, NULL);
  1220. SDPDBG("Printed service attr list %p", svcAttrList);
  1221. }
  1222. #endif
  1223. sdp_record_t *sdp_extract_pdu(const uint8_t *buf, int bufsize, int *scanned)
  1224. {
  1225. int extracted = 0, seqlen = 0;
  1226. uint8_t dtd;
  1227. uint16_t attr;
  1228. sdp_record_t *rec = sdp_record_alloc();
  1229. const uint8_t *p = buf;
  1230. *scanned = sdp_extract_seqtype(buf, bufsize, &dtd, &seqlen);
  1231. p += *scanned;
  1232. bufsize -= *scanned;
  1233. rec->attrlist = NULL;
  1234. while (extracted < seqlen && bufsize > 0) {
  1235. int n = sizeof(uint8_t), attrlen = 0;
  1236. sdp_data_t *data = NULL;
  1237. SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d",
  1238. seqlen, extracted);
  1239. if (bufsize < n + (int) sizeof(uint16_t)) {
  1240. SDPERR("Unexpected end of packet");
  1241. break;
  1242. }
  1243. dtd = *(uint8_t *) p;
  1244. attr = bt_get_be16(p + n);
  1245. n += sizeof(uint16_t);
  1246. SDPDBG("DTD of attrId : %d Attr id : 0x%x ", dtd, attr);
  1247. data = sdp_extract_attr(p + n, bufsize - n, &attrlen, rec);
  1248. SDPDBG("Attr id : 0x%x attrValueLength : %d", attr, attrlen);
  1249. n += attrlen;
  1250. if (data == NULL) {
  1251. SDPDBG("Terminating extraction of attributes");
  1252. break;
  1253. }
  1254. if (attr == SDP_ATTR_RECORD_HANDLE)
  1255. rec->handle = data->val.uint32;
  1256. if (attr == SDP_ATTR_SVCLASS_ID_LIST)
  1257. extract_svclass_uuid(data, &rec->svclass);
  1258. extracted += n;
  1259. p += n;
  1260. bufsize -= n;
  1261. sdp_attr_replace(rec, attr, data);
  1262. SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d",
  1263. seqlen, extracted);
  1264. }
  1265. #ifdef SDP_DEBUG
  1266. SDPDBG("Successful extracting of Svc Rec attributes");
  1267. sdp_print_service_attr(rec->attrlist);
  1268. #endif
  1269. *scanned += seqlen;
  1270. return rec;
  1271. }
  1272. static void sdp_copy_pattern(void *value, void *udata)
  1273. {
  1274. uuid_t *uuid = value;
  1275. sdp_record_t *rec = udata;
  1276. sdp_pattern_add_uuid(rec, uuid);
  1277. }
  1278. static void *sdp_data_value(sdp_data_t *data, uint32_t *len)
  1279. {
  1280. void *val = NULL;
  1281. switch (data->dtd) {
  1282. case SDP_DATA_NIL:
  1283. break;
  1284. case SDP_UINT8:
  1285. val = &data->val.uint8;
  1286. break;
  1287. case SDP_INT8:
  1288. case SDP_BOOL:
  1289. val = &data->val.int8;
  1290. break;
  1291. case SDP_UINT16:
  1292. val = &data->val.uint16;
  1293. break;
  1294. case SDP_INT16:
  1295. val = &data->val.int16;
  1296. break;
  1297. case SDP_UINT32:
  1298. val = &data->val.uint32;
  1299. break;
  1300. case SDP_INT32:
  1301. val = &data->val.int32;
  1302. break;
  1303. case SDP_INT64:
  1304. val = &data->val.int64;
  1305. break;
  1306. case SDP_UINT64:
  1307. val = &data->val.uint64;
  1308. break;
  1309. case SDP_UINT128:
  1310. val = &data->val.uint128;
  1311. break;
  1312. case SDP_INT128:
  1313. val = &data->val.int128;
  1314. break;
  1315. case SDP_UUID16:
  1316. val = &data->val.uuid.value.uuid16;
  1317. break;
  1318. case SDP_UUID32:
  1319. val = &data->val.uuid.value.uuid32;
  1320. break;
  1321. case SDP_UUID128:
  1322. val = &data->val.uuid.value.uuid128;
  1323. break;
  1324. case SDP_URL_STR8:
  1325. case SDP_URL_STR16:
  1326. case SDP_TEXT_STR8:
  1327. case SDP_TEXT_STR16:
  1328. case SDP_URL_STR32:
  1329. case SDP_TEXT_STR32:
  1330. val = data->val.str;
  1331. if (len)
  1332. *len = data->unitSize - 1;
  1333. break;
  1334. case SDP_ALT8:
  1335. case SDP_ALT16:
  1336. case SDP_ALT32:
  1337. case SDP_SEQ8:
  1338. case SDP_SEQ16:
  1339. case SDP_SEQ32:
  1340. val = sdp_copy_seq(data->val.dataseq);
  1341. break;
  1342. }
  1343. return val;
  1344. }
  1345. static sdp_data_t *sdp_copy_seq(sdp_data_t *data)
  1346. {
  1347. sdp_data_t *tmp, *seq = NULL, *cur = NULL;
  1348. for (tmp = data; tmp; tmp = tmp->next) {
  1349. sdp_data_t *datatmp;
  1350. void *value;
  1351. value = sdp_data_value(tmp, NULL);
  1352. datatmp = sdp_data_alloc_with_length(tmp->dtd, value,
  1353. tmp->unitSize);
  1354. if (cur)
  1355. cur->next = datatmp;
  1356. else
  1357. seq = datatmp;
  1358. cur = datatmp;
  1359. }
  1360. return seq;
  1361. }
  1362. static void sdp_copy_attrlist(void *value, void *udata)
  1363. {
  1364. sdp_data_t *data = value;
  1365. sdp_record_t *rec = udata;
  1366. void *val;
  1367. uint32_t len = 0;
  1368. val = sdp_data_value(data, &len);
  1369. if (!len)
  1370. sdp_attr_add_new(rec, data->attrId, data->dtd, val);
  1371. else
  1372. sdp_attr_add_new_with_length(rec, data->attrId,
  1373. data->dtd, val, len);
  1374. }
  1375. sdp_record_t *sdp_copy_record(sdp_record_t *rec)
  1376. {
  1377. sdp_record_t *cpy;
  1378. cpy = sdp_record_alloc();
  1379. cpy->handle = rec->handle;
  1380. sdp_list_foreach(rec->pattern, sdp_copy_pattern, cpy);
  1381. sdp_list_foreach(rec->attrlist, sdp_copy_attrlist, cpy);
  1382. cpy->svclass = rec->svclass;
  1383. return cpy;
  1384. }
  1385. #ifdef SDP_DEBUG
  1386. static void print_dataseq(sdp_data_t *p)
  1387. {
  1388. sdp_data_t *d;
  1389. for (d = p; d; d = d->next)
  1390. sdp_data_print(d);
  1391. }
  1392. #endif
  1393. void sdp_record_print(const sdp_record_t *rec)
  1394. {
  1395. sdp_data_t *d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY);
  1396. if (d && SDP_IS_TEXT_STR(d->dtd))
  1397. printf("Service Name: %.*s\n", d->unitSize, d->val.str);
  1398. d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY);
  1399. if (d && SDP_IS_TEXT_STR(d->dtd))
  1400. printf("Service Description: %.*s\n", d->unitSize, d->val.str);
  1401. d = sdp_data_get(rec, SDP_ATTR_PROVNAME_PRIMARY);
  1402. if (d && SDP_IS_TEXT_STR(d->dtd))
  1403. printf("Service Provider: %.*s\n", d->unitSize, d->val.str);
  1404. }
  1405. #ifdef SDP_DEBUG
  1406. void sdp_data_print(sdp_data_t *d)
  1407. {
  1408. switch (d->dtd) {
  1409. case SDP_DATA_NIL:
  1410. SDPDBG("NIL");
  1411. break;
  1412. case SDP_BOOL:
  1413. case SDP_UINT8:
  1414. case SDP_UINT16:
  1415. case SDP_UINT32:
  1416. case SDP_UINT64:
  1417. case SDP_UINT128:
  1418. case SDP_INT8:
  1419. case SDP_INT16:
  1420. case SDP_INT32:
  1421. case SDP_INT64:
  1422. case SDP_INT128:
  1423. SDPDBG("Integer : 0x%x", d->val.uint32);
  1424. break;
  1425. case SDP_UUID16:
  1426. case SDP_UUID32:
  1427. case SDP_UUID128:
  1428. SDPDBG("UUID");
  1429. sdp_uuid_print(&d->val.uuid);
  1430. break;
  1431. case SDP_TEXT_STR8:
  1432. case SDP_TEXT_STR16:
  1433. case SDP_TEXT_STR32:
  1434. SDPDBG("Text : %s", d->val.str);
  1435. break;
  1436. case SDP_URL_STR8:
  1437. case SDP_URL_STR16:
  1438. case SDP_URL_STR32:
  1439. SDPDBG("URL : %s", d->val.str);
  1440. break;
  1441. case SDP_SEQ8:
  1442. case SDP_SEQ16:
  1443. case SDP_SEQ32:
  1444. print_dataseq(d->val.dataseq);
  1445. break;
  1446. case SDP_ALT8:
  1447. case SDP_ALT16:
  1448. case SDP_ALT32:
  1449. SDPDBG("Data Sequence Alternates");
  1450. print_dataseq(d->val.dataseq);
  1451. break;
  1452. }
  1453. }
  1454. #endif
  1455. sdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attrId)
  1456. {
  1457. if (rec && rec->attrlist) {
  1458. sdp_data_t sdpTemplate;
  1459. sdp_list_t *p;
  1460. sdpTemplate.attrId = attrId;
  1461. p = sdp_list_find(rec->attrlist, &sdpTemplate, sdp_attrid_comp_func);
  1462. if (p)
  1463. return p->data;
  1464. }
  1465. return NULL;
  1466. }
  1467. static int sdp_send_req(sdp_session_t *session, uint8_t *buf, uint32_t size)
  1468. {
  1469. uint32_t sent = 0;
  1470. while (sent < size) {
  1471. int n = send(session->sock, buf + sent, size - sent, 0);
  1472. if (n < 0)
  1473. return -1;
  1474. sent += n;
  1475. }
  1476. return 0;
  1477. }
  1478. static int sdp_read_rsp(sdp_session_t *session, uint8_t *buf, uint32_t size)
  1479. {
  1480. fd_set readFds;
  1481. struct timeval timeout = { SDP_RESPONSE_TIMEOUT, 0 };
  1482. FD_ZERO(&readFds);
  1483. FD_SET(session->sock, &readFds);
  1484. SDPDBG("Waiting for response");
  1485. if (select(session->sock + 1, &readFds, NULL, NULL, &timeout) == 0) {
  1486. SDPERR("Client timed out");
  1487. errno = ETIMEDOUT;
  1488. return -1;
  1489. }
  1490. return recv(session->sock, buf, size, 0);
  1491. }
  1492. /*
  1493. * generic send request, wait for response method.
  1494. */
  1495. int sdp_send_req_w4_rsp(sdp_session_t *session, uint8_t *reqbuf,
  1496. uint8_t *rspbuf, uint32_t reqsize, uint32_t *rspsize)
  1497. {
  1498. int n;
  1499. sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *) reqbuf;
  1500. sdp_pdu_hdr_t *rsphdr = (sdp_pdu_hdr_t *) rspbuf;
  1501. SDPDBG("");
  1502. if (0 > sdp_send_req(session, reqbuf, reqsize)) {
  1503. SDPERR("Error sending data:%m");
  1504. return -1;
  1505. }
  1506. n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE);
  1507. if (0 > n)
  1508. return -1;
  1509. SDPDBG("Read : %d", n);
  1510. if (n == 0 || reqhdr->tid != rsphdr->tid) {
  1511. errno = EPROTO;
  1512. return -1;
  1513. }
  1514. *rspsize = n;
  1515. return 0;
  1516. }
  1517. /*
  1518. * singly-linked lists (after openobex implementation)
  1519. */
  1520. sdp_list_t *sdp_list_append(sdp_list_t *p, void *d)
  1521. {
  1522. sdp_list_t *q, *n = malloc(sizeof(sdp_list_t));
  1523. if (!n)
  1524. return NULL;
  1525. n->data = d;
  1526. n->next = 0;
  1527. if (!p)
  1528. return n;
  1529. for (q = p; q->next; q = q->next);
  1530. q->next = n;
  1531. return p;
  1532. }
  1533. sdp_list_t *sdp_list_remove(sdp_list_t *list, void *d)
  1534. {
  1535. sdp_list_t *p, *q;
  1536. for (q = 0, p = list; p; q = p, p = p->next)
  1537. if (p->data == d) {
  1538. if (q)
  1539. q->next = p->next;
  1540. else
  1541. list = p->next;
  1542. free(p);
  1543. break;
  1544. }
  1545. return list;
  1546. }
  1547. sdp_list_t *sdp_list_insert_sorted(sdp_list_t *list, void *d,
  1548. sdp_comp_func_t f)
  1549. {
  1550. sdp_list_t *q, *p, *n;
  1551. n = malloc(sizeof(sdp_list_t));
  1552. if (!n)
  1553. return NULL;
  1554. n->data = d;
  1555. for (q = 0, p = list; p; q = p, p = p->next)
  1556. if (f(p->data, d) >= 0)
  1557. break;
  1558. /* insert between q and p; if !q insert at head */
  1559. if (q)
  1560. q->next = n;
  1561. else
  1562. list = n;
  1563. n->next = p;
  1564. return list;
  1565. }
  1566. /*
  1567. * Every element of the list points to things which need
  1568. * to be free()'d. This method frees the list's contents
  1569. */
  1570. void sdp_list_free(sdp_list_t *list, sdp_free_func_t f)
  1571. {
  1572. sdp_list_t *next;
  1573. while (list) {
  1574. next = list->next;
  1575. if (f)
  1576. f(list->data);
  1577. free(list);
  1578. list = next;
  1579. }
  1580. }
  1581. static inline int __find_port(sdp_data_t *seq, int proto)
  1582. {
  1583. if (!seq || !seq->next)
  1584. return 0;
  1585. if (SDP_IS_UUID(seq->dtd) && sdp_uuid_to_proto(&seq->val.uuid) == proto) {
  1586. seq = seq->next;
  1587. switch (seq->dtd) {
  1588. case SDP_UINT8:
  1589. return seq->val.uint8;
  1590. case SDP_UINT16:
  1591. return seq->val.uint16;
  1592. }
  1593. }
  1594. return 0;
  1595. }
  1596. int sdp_get_proto_port(const sdp_list_t *list, int proto)
  1597. {
  1598. if (proto != L2CAP_UUID && proto != RFCOMM_UUID) {
  1599. errno = EINVAL;
  1600. return -1;
  1601. }
  1602. for (; list; list = list->next) {
  1603. sdp_list_t *p;
  1604. for (p = list->data; p; p = p->next) {
  1605. sdp_data_t *seq = p->data;
  1606. int port = __find_port(seq, proto);
  1607. if (port)
  1608. return port;
  1609. }
  1610. }
  1611. return 0;
  1612. }
  1613. sdp_data_t *sdp_get_proto_desc(sdp_list_t *list, int proto)
  1614. {
  1615. for (; list; list = list->next) {
  1616. sdp_list_t *p;
  1617. for (p = list->data; p; p = p->next) {
  1618. sdp_data_t *seq = p->data;
  1619. if (SDP_IS_UUID(seq->dtd) &&
  1620. sdp_uuid_to_proto(&seq->val.uuid) == proto)
  1621. return seq->next;
  1622. }
  1623. }
  1624. return NULL;
  1625. }
  1626. static int sdp_get_proto_descs(uint16_t attr_id, const sdp_record_t *rec,
  1627. sdp_list_t **pap)
  1628. {
  1629. sdp_data_t *pdlist, *curr;
  1630. sdp_list_t *ap = NULL;
  1631. pdlist = sdp_data_get(rec, attr_id);
  1632. if (pdlist == NULL) {
  1633. errno = ENODATA;
  1634. return -1;
  1635. }
  1636. SDPDBG("Attribute value type: 0x%02x", pdlist->dtd);
  1637. if (attr_id == SDP_ATTR_ADD_PROTO_DESC_LIST) {
  1638. if (!SDP_IS_SEQ(pdlist->dtd)) {
  1639. errno = EINVAL;
  1640. return -1;
  1641. }
  1642. pdlist = pdlist->val.dataseq;
  1643. }
  1644. for (; pdlist; pdlist = pdlist->next) {
  1645. sdp_list_t *pds = NULL;
  1646. if (!SDP_IS_SEQ(pdlist->dtd) && !SDP_IS_ALT(pdlist->dtd))
  1647. goto failed;
  1648. for (curr = pdlist->val.dataseq; curr; curr = curr->next) {
  1649. if (!SDP_IS_SEQ(curr->dtd)) {
  1650. sdp_list_free(pds, NULL);
  1651. goto failed;
  1652. }
  1653. pds = sdp_list_append(pds, curr->val.dataseq);
  1654. }
  1655. ap = sdp_list_append(ap, pds);
  1656. }
  1657. *pap = ap;
  1658. return 0;
  1659. failed:
  1660. sdp_list_foreach(ap, (sdp_list_func_t) sdp_list_free, NULL);
  1661. sdp_list_free(ap, NULL);
  1662. errno = EINVAL;
  1663. return -1;
  1664. }
  1665. int sdp_get_access_protos(const sdp_record_t *rec, sdp_list_t **pap)
  1666. {
  1667. return sdp_get_proto_descs(SDP_ATTR_PROTO_DESC_LIST, rec, pap);
  1668. }
  1669. int sdp_get_add_access_protos(const sdp_record_t *rec, sdp_list_t **pap)
  1670. {
  1671. return sdp_get_proto_descs(SDP_ATTR_ADD_PROTO_DESC_LIST, rec, pap);
  1672. }
  1673. int sdp_get_uuidseq_attr(const sdp_record_t *rec, uint16_t attr,
  1674. sdp_list_t **seqp)
  1675. {
  1676. sdp_data_t *sdpdata = sdp_data_get(rec, attr);
  1677. *seqp = NULL;
  1678. if (sdpdata && SDP_IS_SEQ(sdpdata->dtd)) {
  1679. sdp_data_t *d;
  1680. for (d = sdpdata->val.dataseq; d; d = d->next) {
  1681. uuid_t *u;
  1682. if (d->dtd < SDP_UUID16 || d->dtd > SDP_UUID128) {
  1683. errno = EINVAL;
  1684. goto fail;
  1685. }
  1686. u = malloc(sizeof(uuid_t));
  1687. if (!u)
  1688. goto fail;
  1689. *u = d->val.uuid;
  1690. *seqp = sdp_list_append(*seqp, u);
  1691. }
  1692. return 0;
  1693. }
  1694. fail:
  1695. sdp_list_free(*seqp, free);
  1696. *seqp = NULL;
  1697. return -1;
  1698. }
  1699. int sdp_set_uuidseq_attr(sdp_record_t *rec, uint16_t aid, sdp_list_t *seq)
  1700. {
  1701. int status = 0, i, len;
  1702. void **dtds, **values;
  1703. uint8_t uuid16 = SDP_UUID16;
  1704. uint8_t uuid32 = SDP_UUID32;
  1705. uint8_t uuid128 = SDP_UUID128;
  1706. sdp_list_t *p;
  1707. len = sdp_list_len(seq);
  1708. if (!seq || len == 0)
  1709. return -1;
  1710. dtds = malloc(len * sizeof(void *));
  1711. if (!dtds)
  1712. return -1;
  1713. values = malloc(len * sizeof(void *));
  1714. if (!values) {
  1715. free(dtds);
  1716. return -1;
  1717. }
  1718. for (p = seq, i = 0; i < len; i++, p = p->next) {
  1719. uuid_t *uuid = p->data;
  1720. if (uuid)
  1721. switch (uuid->type) {
  1722. case SDP_UUID16:
  1723. dtds[i] = &uuid16;
  1724. values[i] = &uuid->value.uuid16;
  1725. break;
  1726. case SDP_UUID32:
  1727. dtds[i] = &uuid32;
  1728. values[i] = &uuid->value.uuid32;
  1729. break;
  1730. case SDP_UUID128:
  1731. dtds[i] = &uuid128;
  1732. values[i] = &uuid->value.uuid128;
  1733. break;
  1734. default:
  1735. status = -1;
  1736. break;
  1737. }
  1738. else {
  1739. status = -1;
  1740. break;
  1741. }
  1742. }
  1743. if (status == 0) {
  1744. sdp_data_t *data = sdp_seq_alloc(dtds, values, len);
  1745. sdp_attr_replace(rec, aid, data);
  1746. sdp_pattern_add_uuidseq(rec, seq);
  1747. }
  1748. free(dtds);
  1749. free(values);
  1750. return status;
  1751. }
  1752. int sdp_get_lang_attr(const sdp_record_t *rec, sdp_list_t **langSeq)
  1753. {
  1754. sdp_lang_attr_t *lang;
  1755. sdp_data_t *sdpdata, *curr_data;
  1756. *langSeq = NULL;
  1757. sdpdata = sdp_data_get(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST);
  1758. if (sdpdata == NULL) {
  1759. errno = ENODATA;
  1760. return -1;
  1761. }
  1762. if (!SDP_IS_SEQ(sdpdata->dtd))
  1763. goto invalid;
  1764. curr_data = sdpdata->val.dataseq;
  1765. while (curr_data) {
  1766. sdp_data_t *pCode, *pEncoding, *pOffset;
  1767. pCode = curr_data;
  1768. if (pCode->dtd != SDP_UINT16)
  1769. goto invalid;
  1770. /* LanguageBaseAttributeIDList entries are always grouped as
  1771. * triplets */
  1772. if (!pCode->next || !pCode->next->next)
  1773. goto invalid;
  1774. pEncoding = pCode->next;
  1775. if (pEncoding->dtd != SDP_UINT16)
  1776. goto invalid;
  1777. pOffset = pEncoding->next;
  1778. if (pOffset->dtd != SDP_UINT16)
  1779. goto invalid;
  1780. lang = malloc(sizeof(sdp_lang_attr_t));
  1781. if (!lang) {
  1782. sdp_list_free(*langSeq, free);
  1783. *langSeq = NULL;
  1784. return -1;
  1785. }
  1786. lang->code_ISO639 = pCode->val.uint16;
  1787. lang->encoding = pEncoding->val.uint16;
  1788. lang->base_offset = pOffset->val.uint16;
  1789. SDPDBG("code_ISO639 : 0x%02x", lang->code_ISO639);
  1790. SDPDBG("encoding : 0x%02x", lang->encoding);
  1791. SDPDBG("base_offfset : 0x%02x", lang->base_offset);
  1792. *langSeq = sdp_list_append(*langSeq, lang);
  1793. curr_data = pOffset->next;
  1794. }
  1795. return 0;
  1796. invalid:
  1797. sdp_list_free(*langSeq, free);
  1798. *langSeq = NULL;
  1799. errno = EINVAL;
  1800. return -1;
  1801. }
  1802. int sdp_get_profile_descs(const sdp_record_t *rec, sdp_list_t **profDescSeq)
  1803. {
  1804. sdp_profile_desc_t *profDesc;
  1805. sdp_data_t *sdpdata, *seq;
  1806. *profDescSeq = NULL;
  1807. sdpdata = sdp_data_get(rec, SDP_ATTR_PFILE_DESC_LIST);
  1808. if (sdpdata == NULL) {
  1809. errno = ENODATA;
  1810. return -1;
  1811. }
  1812. if (!SDP_IS_SEQ(sdpdata->dtd) || sdpdata->val.dataseq == NULL)
  1813. goto invalid;
  1814. for (seq = sdpdata->val.dataseq; seq; seq = seq->next) {
  1815. uuid_t *uuid = NULL;
  1816. uint16_t version = 0x100;
  1817. if (SDP_IS_UUID(seq->dtd)) {
  1818. /* Mac OS X 10.7.3 and old Samsung phones do not comply
  1819. * to the SDP specification for
  1820. * BluetoothProfileDescriptorList. This workaround
  1821. * allows to properly parse UUID/version from SDP
  1822. * record published by these systems. */
  1823. sdp_data_t *next = seq->next;
  1824. uuid = &seq->val.uuid;
  1825. if (next && next->dtd == SDP_UINT16) {
  1826. version = next->val.uint16;
  1827. seq = next;
  1828. }
  1829. } else if (SDP_IS_SEQ(seq->dtd)) {
  1830. sdp_data_t *puuid, *pVnum;
  1831. puuid = seq->val.dataseq;
  1832. if (puuid == NULL || !SDP_IS_UUID(puuid->dtd))
  1833. goto invalid;
  1834. uuid = &puuid->val.uuid;
  1835. pVnum = puuid->next;
  1836. if (pVnum == NULL || pVnum->dtd != SDP_UINT16)
  1837. goto invalid;
  1838. version = pVnum->val.uint16;
  1839. } else
  1840. goto invalid;
  1841. if (uuid != NULL) {
  1842. profDesc = malloc(sizeof(sdp_profile_desc_t));
  1843. if (!profDesc) {
  1844. sdp_list_free(*profDescSeq, free);
  1845. *profDescSeq = NULL;
  1846. return -1;
  1847. }
  1848. profDesc->uuid = *uuid;
  1849. profDesc->version = version;
  1850. #ifdef SDP_DEBUG
  1851. sdp_uuid_print(&profDesc->uuid);
  1852. SDPDBG("Vnum : 0x%04x", profDesc->version);
  1853. #endif
  1854. *profDescSeq = sdp_list_append(*profDescSeq, profDesc);
  1855. }
  1856. }
  1857. return 0;
  1858. invalid:
  1859. sdp_list_free(*profDescSeq, free);
  1860. *profDescSeq = NULL;
  1861. errno = EINVAL;
  1862. return -1;
  1863. }
  1864. int sdp_get_server_ver(const sdp_record_t *rec, sdp_list_t **u16)
  1865. {
  1866. sdp_data_t *d, *curr;
  1867. *u16 = NULL;
  1868. d = sdp_data_get(rec, SDP_ATTR_VERSION_NUM_LIST);
  1869. if (d == NULL) {
  1870. errno = ENODATA;
  1871. return -1;
  1872. }
  1873. if (!SDP_IS_SEQ(d->dtd) || d->val.dataseq == NULL)
  1874. goto invalid;
  1875. for (curr = d->val.dataseq; curr; curr = curr->next) {
  1876. if (curr->dtd != SDP_UINT16)
  1877. goto invalid;
  1878. *u16 = sdp_list_append(*u16, &curr->val.uint16);
  1879. }
  1880. return 0;
  1881. invalid:
  1882. sdp_list_free(*u16, NULL);
  1883. *u16 = NULL;
  1884. errno = EINVAL;
  1885. return -1;
  1886. }
  1887. /* flexible extraction of basic attributes - Jean II */
  1888. /* How do we expect caller to extract predefined data sequences? */
  1889. int sdp_get_int_attr(const sdp_record_t *rec, uint16_t attrid, int *value)
  1890. {
  1891. sdp_data_t *sdpdata = sdp_data_get(rec, attrid);
  1892. if (sdpdata)
  1893. /* Verify that it is what the caller expects */
  1894. if (sdpdata->dtd == SDP_BOOL || sdpdata->dtd == SDP_UINT8 ||
  1895. sdpdata->dtd == SDP_UINT16 || sdpdata->dtd == SDP_UINT32 ||
  1896. sdpdata->dtd == SDP_INT8 || sdpdata->dtd == SDP_INT16 ||
  1897. sdpdata->dtd == SDP_INT32) {
  1898. *value = sdpdata->val.uint32;
  1899. return 0;
  1900. }
  1901. errno = EINVAL;
  1902. return -1;
  1903. }
  1904. int sdp_get_string_attr(const sdp_record_t *rec, uint16_t attrid, char *value,
  1905. int valuelen)
  1906. {
  1907. sdp_data_t *sdpdata = sdp_data_get(rec, attrid);
  1908. if (sdpdata)
  1909. /* Verify that it is what the caller expects */
  1910. if (SDP_IS_TEXT_STR(sdpdata->dtd))
  1911. if ((int) strlen(sdpdata->val.str) < valuelen) {
  1912. strcpy(value, sdpdata->val.str);
  1913. return 0;
  1914. }
  1915. errno = EINVAL;
  1916. return -1;
  1917. }
  1918. #define get_basic_attr(attrID, pAttrValue, fieldName) \
  1919. sdp_data_t *data = sdp_data_get(rec, attrID); \
  1920. if (data) { \
  1921. *pAttrValue = data->val.fieldName; \
  1922. return 0; \
  1923. } \
  1924. errno = EINVAL; \
  1925. return -1;
  1926. int sdp_get_service_id(const sdp_record_t *rec, uuid_t *uuid)
  1927. {
  1928. get_basic_attr(SDP_ATTR_SERVICE_ID, uuid, uuid);
  1929. }
  1930. int sdp_get_group_id(const sdp_record_t *rec, uuid_t *uuid)
  1931. {
  1932. get_basic_attr(SDP_ATTR_GROUP_ID, uuid, uuid);
  1933. }
  1934. int sdp_get_record_state(const sdp_record_t *rec, uint32_t *svcRecState)
  1935. {
  1936. get_basic_attr(SDP_ATTR_RECORD_STATE, svcRecState, uint32);
  1937. }
  1938. int sdp_get_service_avail(const sdp_record_t *rec, uint8_t *svcAvail)
  1939. {
  1940. get_basic_attr(SDP_ATTR_SERVICE_AVAILABILITY, svcAvail, uint8);
  1941. }
  1942. int sdp_get_service_ttl(const sdp_record_t *rec, uint32_t *svcTTLInfo)
  1943. {
  1944. get_basic_attr(SDP_ATTR_SVCINFO_TTL, svcTTLInfo, uint32);
  1945. }
  1946. int sdp_get_database_state(const sdp_record_t *rec, uint32_t *svcDBState)
  1947. {
  1948. get_basic_attr(SDP_ATTR_SVCDB_STATE, svcDBState, uint32);
  1949. }
  1950. /*
  1951. * NOTE that none of the setXXX() functions below will
  1952. * actually update the SDP server, unless the
  1953. * {register, update}sdp_record_t() function is invoked.
  1954. */
  1955. int sdp_attr_add_new(sdp_record_t *rec, uint16_t attr, uint8_t dtd,
  1956. const void *value)
  1957. {
  1958. sdp_data_t *d = sdp_data_alloc(dtd, value);
  1959. if (d) {
  1960. sdp_attr_replace(rec, attr, d);
  1961. return 0;
  1962. }
  1963. return -1;
  1964. }
  1965. static int sdp_attr_add_new_with_length(sdp_record_t *rec,
  1966. uint16_t attr, uint8_t dtd, const void *value, uint32_t len)
  1967. {
  1968. sdp_data_t *d;
  1969. d = sdp_data_alloc_with_length(dtd, value, len);
  1970. if (!d)
  1971. return -1;
  1972. sdp_attr_replace(rec, attr, d);
  1973. return 0;
  1974. }
  1975. /*
  1976. * Set the information attributes of the service
  1977. * pointed to by rec. The attributes are
  1978. * service name, description and provider name
  1979. */
  1980. void sdp_set_info_attr(sdp_record_t *rec, const char *name, const char *prov,
  1981. const char *desc)
  1982. {
  1983. if (name)
  1984. sdp_attr_add_new(rec, SDP_ATTR_SVCNAME_PRIMARY,
  1985. SDP_TEXT_STR8, name);
  1986. if (prov)
  1987. sdp_attr_add_new(rec, SDP_ATTR_PROVNAME_PRIMARY,
  1988. SDP_TEXT_STR8, prov);
  1989. if (desc)
  1990. sdp_attr_add_new(rec, SDP_ATTR_SVCDESC_PRIMARY,
  1991. SDP_TEXT_STR8, desc);
  1992. }
  1993. static sdp_data_t *access_proto_to_dataseq(sdp_record_t *rec, sdp_list_t *proto)
  1994. {
  1995. sdp_data_t *seq = NULL;
  1996. void *dtds[10], *values[10];
  1997. void **seqDTDs, **seqs;
  1998. int i, seqlen;
  1999. sdp_list_t *p;
  2000. seqlen = sdp_list_len(proto);
  2001. seqDTDs = malloc(seqlen * sizeof(void *));
  2002. if (!seqDTDs)
  2003. return NULL;
  2004. seqs = malloc(seqlen * sizeof(void *));
  2005. if (!seqs) {
  2006. free(seqDTDs);
  2007. return NULL;
  2008. }
  2009. for (i = 0, p = proto; p; p = p->next, i++) {
  2010. sdp_list_t *elt = p->data;
  2011. sdp_data_t *s;
  2012. uuid_t *uuid = NULL;
  2013. unsigned int pslen = 0;
  2014. for (; elt && pslen < ARRAY_SIZE(dtds); elt = elt->next, pslen++) {
  2015. sdp_data_t *d = elt->data;
  2016. dtds[pslen] = &d->dtd;
  2017. switch (d->dtd) {
  2018. case SDP_UUID16:
  2019. uuid = (uuid_t *) d;
  2020. values[pslen] = &uuid->value.uuid16;
  2021. break;
  2022. case SDP_UUID32:
  2023. uuid = (uuid_t *) d;
  2024. values[pslen] = &uuid->value.uuid32;
  2025. break;
  2026. case SDP_UUID128:
  2027. uuid = (uuid_t *) d;
  2028. values[pslen] = &uuid->value.uuid128;
  2029. break;
  2030. case SDP_UINT8:
  2031. values[pslen] = &d->val.uint8;
  2032. break;
  2033. case SDP_UINT16:
  2034. values[pslen] = &d->val.uint16;
  2035. break;
  2036. case SDP_SEQ8:
  2037. case SDP_SEQ16:
  2038. case SDP_SEQ32:
  2039. values[pslen] = d;
  2040. break;
  2041. /* FIXME: more */
  2042. }
  2043. }
  2044. s = sdp_seq_alloc(dtds, values, pslen);
  2045. if (s) {
  2046. seqDTDs[i] = &s->dtd;
  2047. seqs[i] = s;
  2048. if (uuid)
  2049. sdp_pattern_add_uuid(rec, uuid);
  2050. }
  2051. }
  2052. seq = sdp_seq_alloc(seqDTDs, seqs, seqlen);
  2053. free(seqDTDs);
  2054. free(seqs);
  2055. return seq;
  2056. }
  2057. /*
  2058. * sets the access protocols of the service specified
  2059. * to the value specified in "access_proto"
  2060. *
  2061. * Note that if there are alternate mechanisms by
  2062. * which the service is accessed, then they should
  2063. * be specified as sequences
  2064. *
  2065. * Using a value of NULL for accessProtocols has
  2066. * effect of removing this attribute (if previously set)
  2067. *
  2068. * This function replaces the existing sdp_access_proto_t
  2069. * structure (if any) with the new one specified.
  2070. *
  2071. * returns 0 if successful or -1 if there is a failure.
  2072. */
  2073. int sdp_set_access_protos(sdp_record_t *rec, const sdp_list_t *ap)
  2074. {
  2075. const sdp_list_t *p;
  2076. sdp_data_t *protos = NULL;
  2077. for (p = ap; p; p = p->next) {
  2078. sdp_data_t *seq = access_proto_to_dataseq(rec, p->data);
  2079. protos = sdp_seq_append(protos, seq);
  2080. }
  2081. sdp_attr_add(rec, SDP_ATTR_PROTO_DESC_LIST, protos);
  2082. return 0;
  2083. }
  2084. int sdp_set_add_access_protos(sdp_record_t *rec, const sdp_list_t *ap)
  2085. {
  2086. const sdp_list_t *p;
  2087. sdp_data_t *protos = NULL;
  2088. for (p = ap; p; p = p->next) {
  2089. sdp_data_t *seq = access_proto_to_dataseq(rec, p->data);
  2090. protos = sdp_seq_append(protos, seq);
  2091. }
  2092. sdp_attr_add(rec, SDP_ATTR_ADD_PROTO_DESC_LIST,
  2093. protos ? sdp_data_alloc(SDP_SEQ8, protos) : NULL);
  2094. return 0;
  2095. }
  2096. /*
  2097. * set the "LanguageBase" attributes of the service record
  2098. * record to the value specified in "langAttrList".
  2099. *
  2100. * "langAttrList" is a linked list of "sdp_lang_attr_t"
  2101. * objects, one for each language in which user visible
  2102. * attributes are present in the service record.
  2103. *
  2104. * Using a value of NULL for langAttrList has
  2105. * effect of removing this attribute (if previously set)
  2106. *
  2107. * This function replaces the exisiting sdp_lang_attr_t
  2108. * structure (if any) with the new one specified.
  2109. *
  2110. * returns 0 if successful or -1 if there is a failure.
  2111. */
  2112. int sdp_set_lang_attr(sdp_record_t *rec, const sdp_list_t *seq)
  2113. {
  2114. uint8_t uint16 = SDP_UINT16;
  2115. int status = 0, i = 0, seqlen = sdp_list_len(seq);
  2116. void **dtds, **values;
  2117. const sdp_list_t *p;
  2118. dtds = malloc(3 * seqlen * sizeof(void *));
  2119. if (!dtds)
  2120. return -1;
  2121. values = malloc(3 * seqlen * sizeof(void *));
  2122. if (!values) {
  2123. free(dtds);
  2124. return -1;
  2125. }
  2126. for (p = seq; p; p = p->next) {
  2127. sdp_lang_attr_t *lang = p->data;
  2128. if (!lang) {
  2129. status = -1;
  2130. break;
  2131. }
  2132. dtds[i] = &uint16;
  2133. values[i] = &lang->code_ISO639;
  2134. i++;
  2135. dtds[i] = &uint16;
  2136. values[i] = &lang->encoding;
  2137. i++;
  2138. dtds[i] = &uint16;
  2139. values[i] = &lang->base_offset;
  2140. i++;
  2141. }
  2142. if (status == 0) {
  2143. sdp_data_t *seq = sdp_seq_alloc(dtds, values, 3 * seqlen);
  2144. sdp_attr_add(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST, seq);
  2145. }
  2146. free(dtds);
  2147. free(values);
  2148. return status;
  2149. }
  2150. /*
  2151. * set the "ServiceID" attribute of the service.
  2152. *
  2153. * This is the UUID of the service.
  2154. *
  2155. * returns 0 if successful or -1 if there is a failure.
  2156. */
  2157. void sdp_set_service_id(sdp_record_t *rec, uuid_t uuid)
  2158. {
  2159. switch (uuid.type) {
  2160. case SDP_UUID16:
  2161. sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID16,
  2162. &uuid.value.uuid16);
  2163. break;
  2164. case SDP_UUID32:
  2165. sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID32,
  2166. &uuid.value.uuid32);
  2167. break;
  2168. case SDP_UUID128:
  2169. sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID128,
  2170. &uuid.value.uuid128);
  2171. break;
  2172. }
  2173. sdp_pattern_add_uuid(rec, &uuid);
  2174. }
  2175. /*
  2176. * set the GroupID attribute of the service record defining a group.
  2177. *
  2178. * This is the UUID of the group.
  2179. *
  2180. * returns 0 if successful or -1 if there is a failure.
  2181. */
  2182. void sdp_set_group_id(sdp_record_t *rec, uuid_t uuid)
  2183. {
  2184. switch (uuid.type) {
  2185. case SDP_UUID16:
  2186. sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID16,
  2187. &uuid.value.uuid16);
  2188. break;
  2189. case SDP_UUID32:
  2190. sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID32,
  2191. &uuid.value.uuid32);
  2192. break;
  2193. case SDP_UUID128:
  2194. sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID128,
  2195. &uuid.value.uuid128);
  2196. break;
  2197. }
  2198. sdp_pattern_add_uuid(rec, &uuid);
  2199. }
  2200. /*
  2201. * set the ProfileDescriptorList attribute of the service record
  2202. * pointed to by record to the value specified in "profileDesc".
  2203. *
  2204. * Each element in the list is an object of type
  2205. * sdp_profile_desc_t which is a definition of the
  2206. * Bluetooth profile that this service conforms to.
  2207. *
  2208. * Using a value of NULL for profileDesc has
  2209. * effect of removing this attribute (if previously set)
  2210. *
  2211. * This function replaces the exisiting ProfileDescriptorList
  2212. * structure (if any) with the new one specified.
  2213. *
  2214. * returns 0 if successful or -1 if there is a failure.
  2215. */
  2216. int sdp_set_profile_descs(sdp_record_t *rec, const sdp_list_t *profiles)
  2217. {
  2218. int status = 0;
  2219. uint8_t uuid16 = SDP_UUID16;
  2220. uint8_t uuid32 = SDP_UUID32;
  2221. uint8_t uuid128 = SDP_UUID128;
  2222. uint8_t uint16 = SDP_UINT16;
  2223. int i = 0, seqlen = sdp_list_len(profiles);
  2224. void **seqDTDs, **seqs;
  2225. const sdp_list_t *p;
  2226. sdp_data_t *pAPSeq;
  2227. seqDTDs = malloc(seqlen * sizeof(void *));
  2228. if (!seqDTDs)
  2229. return -1;
  2230. seqs = malloc(seqlen * sizeof(void *));
  2231. if (!seqs) {
  2232. free(seqDTDs);
  2233. return -1;
  2234. }
  2235. for (p = profiles; p; p = p->next) {
  2236. sdp_data_t *seq;
  2237. void *dtds[2], *values[2];
  2238. sdp_profile_desc_t *profile = p->data;
  2239. if (!profile) {
  2240. status = -1;
  2241. goto end;
  2242. }
  2243. switch (profile->uuid.type) {
  2244. case SDP_UUID16:
  2245. dtds[0] = &uuid16;
  2246. values[0] = &profile->uuid.value.uuid16;
  2247. break;
  2248. case SDP_UUID32:
  2249. dtds[0] = &uuid32;
  2250. values[0] = &profile->uuid.value.uuid32;
  2251. break;
  2252. case SDP_UUID128:
  2253. dtds[0] = &uuid128;
  2254. values[0] = &profile->uuid.value.uuid128;
  2255. break;
  2256. default:
  2257. status = -1;
  2258. goto end;
  2259. }
  2260. dtds[1] = &uint16;
  2261. values[1] = &profile->version;
  2262. seq = sdp_seq_alloc(dtds, values, 2);
  2263. if (seq == NULL) {
  2264. status = -1;
  2265. goto end;
  2266. }
  2267. seqDTDs[i] = &seq->dtd;
  2268. seqs[i] = seq;
  2269. sdp_pattern_add_uuid(rec, &profile->uuid);
  2270. i++;
  2271. }
  2272. pAPSeq = sdp_seq_alloc(seqDTDs, seqs, seqlen);
  2273. sdp_attr_add(rec, SDP_ATTR_PFILE_DESC_LIST, pAPSeq);
  2274. end:
  2275. free(seqDTDs);
  2276. free(seqs);
  2277. return status;
  2278. }
  2279. /*
  2280. * sets various URL attributes of the service
  2281. * pointed to by record. The URL include
  2282. *
  2283. * client: a URL to the client's
  2284. * platform specific (WinCE, PalmOS) executable
  2285. * code that can be used to access this service.
  2286. *
  2287. * doc: a URL pointing to service documentation
  2288. *
  2289. * icon: a URL to an icon that can be used to represent
  2290. * this service.
  2291. *
  2292. * Note that you need to pass NULL for any URLs
  2293. * that you don't want to set or remove
  2294. */
  2295. void sdp_set_url_attr(sdp_record_t *rec, const char *client, const char *doc,
  2296. const char *icon)
  2297. {
  2298. sdp_attr_add_new(rec, SDP_ATTR_CLNT_EXEC_URL, SDP_URL_STR8, client);
  2299. sdp_attr_add_new(rec, SDP_ATTR_DOC_URL, SDP_URL_STR8, doc);
  2300. sdp_attr_add_new(rec, SDP_ATTR_ICON_URL, SDP_URL_STR8, icon);
  2301. }
  2302. uuid_t *sdp_uuid16_create(uuid_t *u, uint16_t val)
  2303. {
  2304. memset(u, 0, sizeof(uuid_t));
  2305. u->type = SDP_UUID16;
  2306. u->value.uuid16 = val;
  2307. return u;
  2308. }
  2309. uuid_t *sdp_uuid32_create(uuid_t *u, uint32_t val)
  2310. {
  2311. memset(u, 0, sizeof(uuid_t));
  2312. u->type = SDP_UUID32;
  2313. u->value.uuid32 = val;
  2314. return u;
  2315. }
  2316. uuid_t *sdp_uuid128_create(uuid_t *u, const void *val)
  2317. {
  2318. memset(u, 0, sizeof(uuid_t));
  2319. u->type = SDP_UUID128;
  2320. memcpy(&u->value.uuid128, val, sizeof(uint128_t));
  2321. return u;
  2322. }
  2323. /*
  2324. * UUID comparison function
  2325. * returns 0 if uuidValue1 == uuidValue2 else -1
  2326. */
  2327. int sdp_uuid_cmp(const void *p1, const void *p2)
  2328. {
  2329. uuid_t *u1 = sdp_uuid_to_uuid128(p1);
  2330. uuid_t *u2 = sdp_uuid_to_uuid128(p2);
  2331. int ret;
  2332. ret = sdp_uuid128_cmp(u1, u2);
  2333. bt_free(u1);
  2334. bt_free(u2);
  2335. return ret;
  2336. }
  2337. /*
  2338. * UUID comparison function
  2339. * returns 0 if uuidValue1 == uuidValue2 else -1
  2340. */
  2341. int sdp_uuid16_cmp(const void *p1, const void *p2)
  2342. {
  2343. const uuid_t *u1 = p1;
  2344. const uuid_t *u2 = p2;
  2345. return memcmp(&u1->value.uuid16, &u2->value.uuid16, sizeof(uint16_t));
  2346. }
  2347. /*
  2348. * UUID comparison function
  2349. * returns 0 if uuidValue1 == uuidValue2 else -1
  2350. */
  2351. int sdp_uuid128_cmp(const void *p1, const void *p2)
  2352. {
  2353. const uuid_t *u1 = p1;
  2354. const uuid_t *u2 = p2;
  2355. return memcmp(&u1->value.uuid128, &u2->value.uuid128, sizeof(uint128_t));
  2356. }
  2357. /*
  2358. * 128 to 16 bit and 32 to 16 bit UUID conversion functions
  2359. * yet to be implemented. Note that the input is in NBO in
  2360. * both 32 and 128 bit UUIDs and conversion is needed
  2361. */
  2362. void sdp_uuid16_to_uuid128(uuid_t *uuid128, const uuid_t *uuid16)
  2363. {
  2364. /*
  2365. * We have a 16 bit value, which needs to be added to
  2366. * bytes 3 and 4 (at indices 2 and 3) of the Bluetooth base
  2367. */
  2368. unsigned short data1;
  2369. /* allocate a 128bit UUID and init to the Bluetooth base UUID */
  2370. uuid128->value.uuid128 = bluetooth_base_uuid;
  2371. uuid128->type = SDP_UUID128;
  2372. /* extract bytes 2 and 3 of 128bit BT base UUID */
  2373. memcpy(&data1, &bluetooth_base_uuid.data[2], 2);
  2374. /* add the given UUID (16 bits) */
  2375. data1 += htons(uuid16->value.uuid16);
  2376. /* set bytes 2 and 3 of the 128 bit value */
  2377. memcpy(&uuid128->value.uuid128.data[2], &data1, 2);
  2378. }
  2379. void sdp_uuid32_to_uuid128(uuid_t *uuid128, const uuid_t *uuid32)
  2380. {
  2381. /*
  2382. * We have a 32 bit value, which needs to be added to
  2383. * bytes 1->4 (at indices 0 thru 3) of the Bluetooth base
  2384. */
  2385. unsigned int data0;
  2386. /* allocate a 128bit UUID and init to the Bluetooth base UUID */
  2387. uuid128->value.uuid128 = bluetooth_base_uuid;
  2388. uuid128->type = SDP_UUID128;
  2389. /* extract first 4 bytes */
  2390. memcpy(&data0, &bluetooth_base_uuid.data[0], 4);
  2391. /* add the given UUID (32bits) */
  2392. data0 += htonl(uuid32->value.uuid32);
  2393. /* set the 4 bytes of the 128 bit value */
  2394. memcpy(&uuid128->value.uuid128.data[0], &data0, 4);
  2395. }
  2396. uuid_t *sdp_uuid_to_uuid128(const uuid_t *uuid)
  2397. {
  2398. uuid_t *uuid128 = bt_malloc0(sizeof(uuid_t));
  2399. if (!uuid128)
  2400. return NULL;
  2401. switch (uuid->type) {
  2402. case SDP_UUID128:
  2403. *uuid128 = *uuid;
  2404. break;
  2405. case SDP_UUID32:
  2406. sdp_uuid32_to_uuid128(uuid128, uuid);
  2407. break;
  2408. case SDP_UUID16:
  2409. sdp_uuid16_to_uuid128(uuid128, uuid);
  2410. break;
  2411. }
  2412. return uuid128;
  2413. }
  2414. /*
  2415. * converts a 128-bit uuid to a 16/32-bit one if possible
  2416. * returns true if uuid contains a 16/32-bit UUID at exit
  2417. */
  2418. int sdp_uuid128_to_uuid(uuid_t *uuid)
  2419. {
  2420. uint128_t *b = &bluetooth_base_uuid;
  2421. uint128_t *u = &uuid->value.uuid128;
  2422. uint32_t data;
  2423. unsigned int i;
  2424. if (uuid->type != SDP_UUID128)
  2425. return 1;
  2426. for (i = 4; i < sizeof(b->data); i++)
  2427. if (b->data[i] != u->data[i])
  2428. return 0;
  2429. memcpy(&data, u->data, 4);
  2430. data = htonl(data);
  2431. if (data <= 0xffff) {
  2432. uuid->type = SDP_UUID16;
  2433. uuid->value.uuid16 = (uint16_t) data;
  2434. } else {
  2435. uuid->type = SDP_UUID32;
  2436. uuid->value.uuid32 = data;
  2437. }
  2438. return 1;
  2439. }
  2440. /*
  2441. * convert a UUID to the 16-bit short-form
  2442. */
  2443. int sdp_uuid_to_proto(uuid_t *uuid)
  2444. {
  2445. uuid_t u = *uuid;
  2446. if (sdp_uuid128_to_uuid(&u)) {
  2447. switch (u.type) {
  2448. case SDP_UUID16:
  2449. return u.value.uuid16;
  2450. case SDP_UUID32:
  2451. return u.value.uuid32;
  2452. }
  2453. }
  2454. return 0;
  2455. }
  2456. /*
  2457. * This function appends data to the PDU buffer "dst" from source "src".
  2458. * The data length is also computed and set.
  2459. * Should the PDU length exceed 2^8, then sequence type is
  2460. * set accordingly and the data is memmove()'d.
  2461. */
  2462. void sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len)
  2463. {
  2464. uint8_t *p = dst->data;
  2465. uint8_t dtd = *p;
  2466. SDPDBG("Append src size: %d", len);
  2467. SDPDBG("Append dst size: %d", dst->data_size);
  2468. SDPDBG("Dst buffer size: %d", dst->buf_size);
  2469. if (dst->data_size + len > dst->buf_size) {
  2470. SDPERR("Cannot append");
  2471. return;
  2472. }
  2473. if (dst->data_size == 0 && dtd == 0) {
  2474. /* create initial sequence */
  2475. *p = SDP_SEQ8;
  2476. dst->data_size += sizeof(uint8_t);
  2477. /* reserve space for sequence size */
  2478. dst->data_size += sizeof(uint8_t);
  2479. }
  2480. memcpy(dst->data + dst->data_size, data, len);
  2481. dst->data_size += len;
  2482. dtd = *(uint8_t *) dst->data;
  2483. if (dst->data_size > UCHAR_MAX && dtd == SDP_SEQ8) {
  2484. short offset = sizeof(uint8_t) + sizeof(uint8_t);
  2485. memmove(dst->data + offset + 1, dst->data + offset,
  2486. dst->data_size - offset);
  2487. *p = SDP_SEQ16;
  2488. dst->data_size += 1;
  2489. }
  2490. dtd = *(uint8_t *) p;
  2491. p += sizeof(uint8_t);
  2492. switch (dtd) {
  2493. case SDP_SEQ8:
  2494. *(uint8_t *) p = dst->data_size - sizeof(uint8_t) - sizeof(uint8_t);
  2495. break;
  2496. case SDP_SEQ16:
  2497. bt_put_be16(dst->data_size - sizeof(uint8_t) - sizeof(uint16_t), p);
  2498. break;
  2499. case SDP_SEQ32:
  2500. bt_put_be32(dst->data_size - sizeof(uint8_t) - sizeof(uint32_t), p);
  2501. break;
  2502. }
  2503. }
  2504. void sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d)
  2505. {
  2506. sdp_buf_t append;
  2507. memset(&append, 0, sizeof(sdp_buf_t));
  2508. sdp_gen_buffer(&append, d);
  2509. append.data = malloc(append.buf_size);
  2510. if (!append.data)
  2511. return;
  2512. sdp_set_attrid(&append, d->attrId);
  2513. sdp_gen_pdu(&append, d);
  2514. sdp_append_to_buf(pdu, append.data, append.data_size);
  2515. free(append.data);
  2516. }
  2517. /*
  2518. * Registers an sdp record.
  2519. *
  2520. * It is incorrect to call this method on a record that
  2521. * has been already registered with the server.
  2522. *
  2523. * Returns zero on success, otherwise -1 (and sets errno).
  2524. */
  2525. int sdp_device_record_register_binary(sdp_session_t *session, bdaddr_t *device, uint8_t *data, uint32_t size, uint8_t flags, uint32_t *handle)
  2526. {
  2527. uint8_t *req, *rsp, *p;
  2528. uint32_t reqsize, rspsize;
  2529. sdp_pdu_hdr_t *reqhdr, *rsphdr;
  2530. int status;
  2531. SDPDBG("");
  2532. if (!session->local) {
  2533. errno = EREMOTE;
  2534. return -1;
  2535. }
  2536. req = malloc(SDP_REQ_BUFFER_SIZE);
  2537. rsp = malloc(SDP_RSP_BUFFER_SIZE);
  2538. if (req == NULL || rsp == NULL) {
  2539. status = -1;
  2540. errno = ENOMEM;
  2541. goto end;
  2542. }
  2543. reqhdr = (sdp_pdu_hdr_t *)req;
  2544. reqhdr->pdu_id = SDP_SVC_REGISTER_REQ;
  2545. reqhdr->tid = htons(sdp_gen_tid(session));
  2546. reqsize = sizeof(sdp_pdu_hdr_t) + 1;
  2547. p = req + sizeof(sdp_pdu_hdr_t);
  2548. if (bacmp(device, BDADDR_ANY)) {
  2549. *p++ = flags | SDP_DEVICE_RECORD;
  2550. bacpy((bdaddr_t *) p, device);
  2551. p += sizeof(bdaddr_t);
  2552. reqsize += sizeof(bdaddr_t);
  2553. } else
  2554. *p++ = flags;
  2555. memcpy(p, data, size);
  2556. reqsize += size;
  2557. reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
  2558. status = sdp_send_req_w4_rsp(session, req, rsp, reqsize, &rspsize);
  2559. if (status < 0)
  2560. goto end;
  2561. if (rspsize < sizeof(sdp_pdu_hdr_t)) {
  2562. SDPERR("Unexpected end of packet");
  2563. errno = EPROTO;
  2564. status = -1;
  2565. goto end;
  2566. }
  2567. rsphdr = (sdp_pdu_hdr_t *) rsp;
  2568. p = rsp + sizeof(sdp_pdu_hdr_t);
  2569. if (rsphdr->pdu_id == SDP_ERROR_RSP) {
  2570. /* Invalid service record */
  2571. errno = EINVAL;
  2572. status = -1;
  2573. } else if (rsphdr->pdu_id != SDP_SVC_REGISTER_RSP) {
  2574. errno = EPROTO;
  2575. status = -1;
  2576. } else {
  2577. if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint32_t)) {
  2578. SDPERR("Unexpected end of packet");
  2579. errno = EPROTO;
  2580. status = -1;
  2581. goto end;
  2582. }
  2583. if (handle)
  2584. *handle = bt_get_be32(p);
  2585. }
  2586. end:
  2587. free(req);
  2588. free(rsp);
  2589. return status;
  2590. }
  2591. int sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec, uint8_t flags)
  2592. {
  2593. sdp_buf_t pdu;
  2594. uint32_t handle;
  2595. int err;
  2596. SDPDBG("");
  2597. if (rec->handle && rec->handle != 0xffffffff) {
  2598. uint32_t handle = rec->handle;
  2599. sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle);
  2600. sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data);
  2601. }
  2602. if (sdp_gen_record_pdu(rec, &pdu) < 0) {
  2603. errno = ENOMEM;
  2604. return -1;
  2605. }
  2606. err = sdp_device_record_register_binary(session, device,
  2607. pdu.data, pdu.data_size, flags, &handle);
  2608. free(pdu.data);
  2609. if (err == 0) {
  2610. sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle);
  2611. rec->handle = handle;
  2612. sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data);
  2613. }
  2614. return err;
  2615. }
  2616. int sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags)
  2617. {
  2618. return sdp_device_record_register(session, BDADDR_ANY, rec, flags);
  2619. }
  2620. /*
  2621. * unregister a service record
  2622. */
  2623. int sdp_device_record_unregister_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle)
  2624. {
  2625. uint8_t *reqbuf, *rspbuf, *p;
  2626. uint32_t reqsize = 0, rspsize = 0;
  2627. sdp_pdu_hdr_t *reqhdr, *rsphdr;
  2628. int status;
  2629. SDPDBG("");
  2630. if (handle == SDP_SERVER_RECORD_HANDLE) {
  2631. errno = EINVAL;
  2632. return -1;
  2633. }
  2634. if (!session->local) {
  2635. errno = EREMOTE;
  2636. return -1;
  2637. }
  2638. reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
  2639. rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
  2640. if (!reqbuf || !rspbuf) {
  2641. errno = ENOMEM;
  2642. status = -1;
  2643. goto end;
  2644. }
  2645. reqhdr = (sdp_pdu_hdr_t *) reqbuf;
  2646. reqhdr->pdu_id = SDP_SVC_REMOVE_REQ;
  2647. reqhdr->tid = htons(sdp_gen_tid(session));
  2648. p = reqbuf + sizeof(sdp_pdu_hdr_t);
  2649. reqsize = sizeof(sdp_pdu_hdr_t);
  2650. bt_put_be32(handle, p);
  2651. reqsize += sizeof(uint32_t);
  2652. reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
  2653. status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
  2654. if (status < 0)
  2655. goto end;
  2656. if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) {
  2657. SDPERR("Unexpected end of packet");
  2658. errno = EPROTO;
  2659. status = -1;
  2660. goto end;
  2661. }
  2662. rsphdr = (sdp_pdu_hdr_t *) rspbuf;
  2663. p = rspbuf + sizeof(sdp_pdu_hdr_t);
  2664. if (rsphdr->pdu_id == SDP_ERROR_RSP) {
  2665. /* For this case the status always is invalid record handle */
  2666. errno = EINVAL;
  2667. status = -1;
  2668. } else if (rsphdr->pdu_id != SDP_SVC_REMOVE_RSP) {
  2669. errno = EPROTO;
  2670. status = -1;
  2671. } else {
  2672. uint16_t tmp;
  2673. memcpy(&tmp, p, sizeof(tmp));
  2674. status = tmp;
  2675. }
  2676. end:
  2677. free(reqbuf);
  2678. free(rspbuf);
  2679. return status;
  2680. }
  2681. int sdp_device_record_unregister(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec)
  2682. {
  2683. int err;
  2684. err = sdp_device_record_unregister_binary(session, device, rec->handle);
  2685. if (err == 0)
  2686. sdp_record_free(rec);
  2687. return err;
  2688. }
  2689. int sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec)
  2690. {
  2691. return sdp_device_record_unregister(session, BDADDR_ANY, rec);
  2692. }
  2693. /*
  2694. * modify an existing service record
  2695. */
  2696. int sdp_device_record_update_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle, uint8_t *data, uint32_t size)
  2697. {
  2698. return -1;
  2699. }
  2700. int sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp_record_t *rec)
  2701. {
  2702. uint8_t *reqbuf, *rspbuf, *p;
  2703. uint32_t reqsize, rspsize;
  2704. sdp_pdu_hdr_t *reqhdr, *rsphdr;
  2705. uint32_t handle;
  2706. sdp_buf_t pdu;
  2707. int status;
  2708. SDPDBG("");
  2709. handle = rec->handle;
  2710. if (handle == SDP_SERVER_RECORD_HANDLE) {
  2711. errno = EINVAL;
  2712. return -1;
  2713. }
  2714. if (!session->local) {
  2715. errno = EREMOTE;
  2716. return -1;
  2717. }
  2718. reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
  2719. rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
  2720. if (!reqbuf || !rspbuf) {
  2721. errno = ENOMEM;
  2722. status = -1;
  2723. goto end;
  2724. }
  2725. reqhdr = (sdp_pdu_hdr_t *) reqbuf;
  2726. reqhdr->pdu_id = SDP_SVC_UPDATE_REQ;
  2727. reqhdr->tid = htons(sdp_gen_tid(session));
  2728. p = reqbuf + sizeof(sdp_pdu_hdr_t);
  2729. reqsize = sizeof(sdp_pdu_hdr_t);
  2730. bt_put_be32(handle, p);
  2731. reqsize += sizeof(uint32_t);
  2732. p += sizeof(uint32_t);
  2733. if (sdp_gen_record_pdu(rec, &pdu) < 0) {
  2734. errno = ENOMEM;
  2735. status = -1;
  2736. goto end;
  2737. }
  2738. memcpy(p, pdu.data, pdu.data_size);
  2739. reqsize += pdu.data_size;
  2740. free(pdu.data);
  2741. reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
  2742. status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
  2743. if (status < 0)
  2744. goto end;
  2745. if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) {
  2746. SDPERR("Unexpected end of packet");
  2747. errno = EPROTO;
  2748. status = -1;
  2749. goto end;
  2750. }
  2751. SDPDBG("Send req status : %d", status);
  2752. rsphdr = (sdp_pdu_hdr_t *) rspbuf;
  2753. p = rspbuf + sizeof(sdp_pdu_hdr_t);
  2754. if (rsphdr->pdu_id == SDP_ERROR_RSP) {
  2755. /* The status can be invalid sintax or invalid record handle */
  2756. errno = EINVAL;
  2757. status = -1;
  2758. } else if (rsphdr->pdu_id != SDP_SVC_UPDATE_RSP) {
  2759. errno = EPROTO;
  2760. status = -1;
  2761. } else {
  2762. uint16_t tmp;
  2763. memcpy(&tmp, p, sizeof(tmp));
  2764. status = tmp;
  2765. }
  2766. end:
  2767. free(reqbuf);
  2768. free(rspbuf);
  2769. return status;
  2770. }
  2771. int sdp_record_update(sdp_session_t *session, const sdp_record_t *rec)
  2772. {
  2773. return sdp_device_record_update(session, BDADDR_ANY, rec);
  2774. }
  2775. sdp_record_t *sdp_record_alloc(void)
  2776. {
  2777. sdp_record_t *rec = bt_malloc0(sizeof(sdp_record_t));
  2778. if (!rec)
  2779. return NULL;
  2780. rec->handle = 0xffffffff;
  2781. return rec;
  2782. }
  2783. /*
  2784. * Free the contents of a service record
  2785. */
  2786. void sdp_record_free(sdp_record_t *rec)
  2787. {
  2788. sdp_list_free(rec->attrlist, (sdp_free_func_t) sdp_data_free);
  2789. sdp_list_free(rec->pattern, free);
  2790. free(rec);
  2791. }
  2792. void sdp_pattern_add_uuid(sdp_record_t *rec, uuid_t *uuid)
  2793. {
  2794. uuid_t *uuid128 = sdp_uuid_to_uuid128(uuid);
  2795. SDPDBG("Elements in target pattern : %d", sdp_list_len(rec->pattern));
  2796. SDPDBG("Trying to add : 0x%lx", (unsigned long) uuid128);
  2797. if (sdp_list_find(rec->pattern, uuid128, sdp_uuid128_cmp) == NULL)
  2798. rec->pattern = sdp_list_insert_sorted(rec->pattern, uuid128, sdp_uuid128_cmp);
  2799. else
  2800. bt_free(uuid128);
  2801. SDPDBG("Elements in target pattern : %d", sdp_list_len(rec->pattern));
  2802. }
  2803. void sdp_pattern_add_uuidseq(sdp_record_t *rec, sdp_list_t *seq)
  2804. {
  2805. for (; seq; seq = seq->next) {
  2806. uuid_t *uuid = (uuid_t *)seq->data;
  2807. sdp_pattern_add_uuid(rec, uuid);
  2808. }
  2809. }
  2810. /*
  2811. * Extract a sequence of service record handles from a PDU buffer
  2812. * and add the entries to a sdp_list_t. Note that the service record
  2813. * handles are not in "data element sequence" form, but just like
  2814. * an array of service handles
  2815. */
  2816. static void extract_record_handle_seq(uint8_t *pdu, int bufsize, sdp_list_t **seq, int count, unsigned int *scanned)
  2817. {
  2818. sdp_list_t *pSeq = *seq;
  2819. uint8_t *pdata = pdu;
  2820. int n;
  2821. for (n = 0; n < count; n++) {
  2822. uint32_t *pSvcRec;
  2823. if (bufsize < (int) sizeof(uint32_t)) {
  2824. SDPERR("Unexpected end of packet");
  2825. break;
  2826. }
  2827. pSvcRec = malloc(sizeof(uint32_t));
  2828. if (!pSvcRec)
  2829. break;
  2830. *pSvcRec = bt_get_be32(pdata);
  2831. pSeq = sdp_list_append(pSeq, pSvcRec);
  2832. pdata += sizeof(uint32_t);
  2833. *scanned += sizeof(uint32_t);
  2834. bufsize -= sizeof(uint32_t);
  2835. }
  2836. *seq = pSeq;
  2837. }
  2838. /*
  2839. * Generate the attribute sequence pdu form
  2840. * from sdp_list_t elements. Return length of attr seq
  2841. */
  2842. static int gen_dataseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dtd)
  2843. {
  2844. sdp_data_t *dataseq;
  2845. void **types, **values;
  2846. sdp_buf_t buf;
  2847. int i, seqlen = sdp_list_len(seq);
  2848. /* Fill up the value and the dtd arrays */
  2849. SDPDBG("");
  2850. SDPDBG("Seq length : %d", seqlen);
  2851. types = malloc(seqlen * sizeof(void *));
  2852. if (!types)
  2853. return -ENOMEM;
  2854. values = malloc(seqlen * sizeof(void *));
  2855. if (!values) {
  2856. free(types);
  2857. return -ENOMEM;
  2858. }
  2859. for (i = 0; i < seqlen; i++) {
  2860. void *data = seq->data;
  2861. types[i] = &dtd;
  2862. if (SDP_IS_UUID(dtd))
  2863. data = &((uuid_t *)data)->value;
  2864. values[i] = data;
  2865. seq = seq->next;
  2866. }
  2867. dataseq = sdp_seq_alloc(types, values, seqlen);
  2868. if (!dataseq) {
  2869. free(types);
  2870. free(values);
  2871. return -ENOMEM;
  2872. }
  2873. memset(&buf, 0, sizeof(sdp_buf_t));
  2874. sdp_gen_buffer(&buf, dataseq);
  2875. buf.data = malloc(buf.buf_size);
  2876. if (!buf.data) {
  2877. sdp_data_free(dataseq);
  2878. free(types);
  2879. free(values);
  2880. return -ENOMEM;
  2881. }
  2882. SDPDBG("Data Seq : 0x%p", seq);
  2883. seqlen = sdp_gen_pdu(&buf, dataseq);
  2884. SDPDBG("Copying : %d", buf.data_size);
  2885. memcpy(dst, buf.data, buf.data_size);
  2886. sdp_data_free(dataseq);
  2887. free(types);
  2888. free(values);
  2889. free(buf.data);
  2890. return seqlen;
  2891. }
  2892. static int gen_searchseq_pdu(uint8_t *dst, const sdp_list_t *seq)
  2893. {
  2894. uuid_t *uuid = seq->data;
  2895. return gen_dataseq_pdu(dst, seq, uuid->type);
  2896. }
  2897. static int gen_attridseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dataType)
  2898. {
  2899. return gen_dataseq_pdu(dst, seq, dataType);
  2900. }
  2901. typedef struct {
  2902. uint8_t length;
  2903. unsigned char data[16];
  2904. } __attribute__ ((packed)) sdp_cstate_t;
  2905. static int copy_cstate(uint8_t *pdata, int pdata_len, const sdp_cstate_t *cstate)
  2906. {
  2907. if (cstate) {
  2908. uint8_t len = cstate->length;
  2909. if (len >= pdata_len) {
  2910. SDPERR("Continuation state size exceeds internal buffer");
  2911. len = pdata_len - 1;
  2912. }
  2913. *pdata++ = len;
  2914. memcpy(pdata, cstate->data, len);
  2915. return len + 1;
  2916. }
  2917. *pdata = 0;
  2918. return 1;
  2919. }
  2920. /*
  2921. * This is a service search request.
  2922. *
  2923. * INPUT :
  2924. *
  2925. * sdp_list_t *search
  2926. * Singly linked list containing elements of the search
  2927. * pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16)
  2928. * of the service to be searched
  2929. *
  2930. * uint16_t max_rec_num
  2931. * A 16 bit integer which tells the service, the maximum
  2932. * entries that the client can handle in the response. The
  2933. * server is obliged not to return > max_rec_num entries
  2934. *
  2935. * OUTPUT :
  2936. *
  2937. * int return value
  2938. * 0:
  2939. * The request completed successfully. This does not
  2940. * mean the requested services were found
  2941. * -1:
  2942. * On any failure and sets errno
  2943. *
  2944. * sdp_list_t **rsp_list
  2945. * This variable is set on a successful return if there are
  2946. * non-zero service handles. It is a singly linked list of
  2947. * service record handles (uint16_t)
  2948. */
  2949. int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search,
  2950. uint16_t max_rec_num, sdp_list_t **rsp)
  2951. {
  2952. int status = 0;
  2953. uint32_t reqsize = 0, _reqsize;
  2954. uint32_t rspsize = 0, rsplen;
  2955. int seqlen = 0;
  2956. int rec_count;
  2957. unsigned scanned, pdata_len;
  2958. uint8_t *pdata, *_pdata;
  2959. uint8_t *reqbuf, *rspbuf;
  2960. sdp_pdu_hdr_t *reqhdr, *rsphdr;
  2961. sdp_cstate_t *cstate = NULL;
  2962. reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
  2963. rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
  2964. if (!reqbuf || !rspbuf) {
  2965. errno = ENOMEM;
  2966. status = -1;
  2967. goto end;
  2968. }
  2969. reqhdr = (sdp_pdu_hdr_t *) reqbuf;
  2970. reqhdr->pdu_id = SDP_SVC_SEARCH_REQ;
  2971. pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
  2972. reqsize = sizeof(sdp_pdu_hdr_t);
  2973. /* add service class IDs for search */
  2974. seqlen = gen_searchseq_pdu(pdata, search);
  2975. if (seqlen < 0) {
  2976. errno = EINVAL;
  2977. status = -1;
  2978. goto end;
  2979. }
  2980. SDPDBG("Data seq added : %d", seqlen);
  2981. /* set the length and increment the pointer */
  2982. reqsize += seqlen;
  2983. pdata += seqlen;
  2984. /* specify the maximum svc rec count that client expects */
  2985. bt_put_be16(max_rec_num, pdata);
  2986. reqsize += sizeof(uint16_t);
  2987. pdata += sizeof(uint16_t);
  2988. _reqsize = reqsize;
  2989. _pdata = pdata;
  2990. *rsp = NULL;
  2991. do {
  2992. /* Add continuation state or NULL (first time) */
  2993. reqsize = _reqsize + copy_cstate(_pdata,
  2994. SDP_REQ_BUFFER_SIZE - _reqsize, cstate);
  2995. /* Set the request header's param length */
  2996. reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
  2997. reqhdr->tid = htons(sdp_gen_tid(session));
  2998. /*
  2999. * Send the request, wait for response and if
  3000. * no error, set the appropriate values and return
  3001. */
  3002. status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
  3003. if (status < 0)
  3004. goto end;
  3005. if (rspsize < sizeof(sdp_pdu_hdr_t)) {
  3006. SDPERR("Unexpected end of packet");
  3007. status = -1;
  3008. goto end;
  3009. }
  3010. rsphdr = (sdp_pdu_hdr_t *) rspbuf;
  3011. rsplen = ntohs(rsphdr->plen);
  3012. if (rsphdr->pdu_id == SDP_ERROR_RSP) {
  3013. SDPDBG("Status : 0x%x", rsphdr->pdu_id);
  3014. status = -1;
  3015. goto end;
  3016. }
  3017. scanned = 0;
  3018. pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
  3019. pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);
  3020. if (pdata_len < sizeof(uint16_t) + sizeof(uint16_t)) {
  3021. SDPERR("Unexpected end of packet");
  3022. status = -1;
  3023. goto end;
  3024. }
  3025. /* net service record match count */
  3026. pdata += sizeof(uint16_t);
  3027. scanned += sizeof(uint16_t);
  3028. pdata_len -= sizeof(uint16_t);
  3029. rec_count = bt_get_be16(pdata);
  3030. pdata += sizeof(uint16_t);
  3031. scanned += sizeof(uint16_t);
  3032. pdata_len -= sizeof(uint16_t);
  3033. SDPDBG("Current svc count: %d", rec_count);
  3034. SDPDBG("ResponseLength: %d", rsplen);
  3035. if (!rec_count) {
  3036. status = -1;
  3037. goto end;
  3038. }
  3039. extract_record_handle_seq(pdata, pdata_len, rsp, rec_count, &scanned);
  3040. SDPDBG("BytesScanned : %d", scanned);
  3041. if (rsplen > scanned) {
  3042. uint8_t cstate_len;
  3043. if (rspsize < sizeof(sdp_pdu_hdr_t) + scanned + sizeof(uint8_t)) {
  3044. SDPERR("Unexpected end of packet: continuation state data missing");
  3045. status = -1;
  3046. goto end;
  3047. }
  3048. pdata = rspbuf + sizeof(sdp_pdu_hdr_t) + scanned;
  3049. cstate_len = *(uint8_t *) pdata;
  3050. if (cstate_len > 0) {
  3051. cstate = (sdp_cstate_t *)pdata;
  3052. SDPDBG("Cont state length: %d", cstate_len);
  3053. } else
  3054. cstate = NULL;
  3055. }
  3056. } while (cstate);
  3057. end:
  3058. free(reqbuf);
  3059. free(rspbuf);
  3060. return status;
  3061. }
  3062. /*
  3063. * This is a service attribute request.
  3064. *
  3065. * INPUT :
  3066. *
  3067. * uint32_t handle
  3068. * The handle of the service for which the attribute(s) are
  3069. * requested
  3070. *
  3071. * sdp_attrreq_type_t reqtype
  3072. * Attribute identifiers are 16 bit unsigned integers specified
  3073. * in one of 2 ways described below :
  3074. * SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
  3075. * They are the actual attribute identifiers in ascending order
  3076. *
  3077. * SDP_ATTR_REQ_RANGE - 32bit identifier range
  3078. * The high-order 16bits is the start of range
  3079. * the low-order 16bits are the end of range
  3080. * 0x0000 to 0xFFFF gets all attributes
  3081. *
  3082. * sdp_list_t *attrid
  3083. * Singly linked list containing attribute identifiers desired.
  3084. * Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
  3085. * or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
  3086. *
  3087. * OUTPUT :
  3088. * return sdp_record_t *
  3089. * 0:
  3090. * On any error and sets errno
  3091. * !0:
  3092. * The service record
  3093. */
  3094. sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle,
  3095. sdp_attrreq_type_t reqtype, const sdp_list_t *attrids)
  3096. {
  3097. uint32_t reqsize = 0, _reqsize;
  3098. uint32_t rspsize = 0, rsp_count;
  3099. int attr_list_len = 0;
  3100. int seqlen = 0;
  3101. unsigned int pdata_len;
  3102. uint8_t *pdata, *_pdata;
  3103. uint8_t *reqbuf, *rspbuf;
  3104. sdp_pdu_hdr_t *reqhdr, *rsphdr;
  3105. sdp_cstate_t *cstate = NULL;
  3106. uint8_t cstate_len = 0;
  3107. sdp_buf_t rsp_concat_buf;
  3108. sdp_record_t *rec = 0;
  3109. if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) {
  3110. errno = EINVAL;
  3111. return NULL;
  3112. }
  3113. memset(&rsp_concat_buf, 0, sizeof(sdp_buf_t));
  3114. reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
  3115. rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
  3116. if (!reqbuf || !rspbuf) {
  3117. errno = ENOMEM;
  3118. goto end;
  3119. }
  3120. reqhdr = (sdp_pdu_hdr_t *) reqbuf;
  3121. reqhdr->pdu_id = SDP_SVC_ATTR_REQ;
  3122. pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
  3123. reqsize = sizeof(sdp_pdu_hdr_t);
  3124. /* add the service record handle */
  3125. bt_put_be32(handle, pdata);
  3126. reqsize += sizeof(uint32_t);
  3127. pdata += sizeof(uint32_t);
  3128. /* specify the response limit */
  3129. bt_put_be16(65535, pdata);
  3130. reqsize += sizeof(uint16_t);
  3131. pdata += sizeof(uint16_t);
  3132. /* get attr seq PDU form */
  3133. seqlen = gen_attridseq_pdu(pdata, attrids,
  3134. reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32);
  3135. if (seqlen == -1) {
  3136. errno = EINVAL;
  3137. goto end;
  3138. }
  3139. pdata += seqlen;
  3140. reqsize += seqlen;
  3141. SDPDBG("Attr list length : %d", seqlen);
  3142. /* save before Continuation State */
  3143. _pdata = pdata;
  3144. _reqsize = reqsize;
  3145. do {
  3146. int status;
  3147. /* add NULL continuation state */
  3148. reqsize = _reqsize + copy_cstate(_pdata,
  3149. SDP_REQ_BUFFER_SIZE - _reqsize, cstate);
  3150. /* set the request header's param length */
  3151. reqhdr->tid = htons(sdp_gen_tid(session));
  3152. reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
  3153. status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
  3154. if (status < 0)
  3155. goto end;
  3156. if (rspsize < sizeof(sdp_pdu_hdr_t)) {
  3157. SDPERR("Unexpected end of packet");
  3158. goto end;
  3159. }
  3160. rsphdr = (sdp_pdu_hdr_t *) rspbuf;
  3161. if (rsphdr->pdu_id == SDP_ERROR_RSP) {
  3162. SDPDBG("PDU ID : 0x%x", rsphdr->pdu_id);
  3163. goto end;
  3164. }
  3165. pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
  3166. pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);
  3167. if (pdata_len < sizeof(uint16_t)) {
  3168. SDPERR("Unexpected end of packet");
  3169. goto end;
  3170. }
  3171. rsp_count = bt_get_be16(pdata);
  3172. attr_list_len += rsp_count;
  3173. pdata += sizeof(uint16_t);
  3174. pdata_len -= sizeof(uint16_t);
  3175. /*
  3176. * if continuation state set need to re-issue request before
  3177. * parsing
  3178. */
  3179. if (pdata_len < rsp_count + sizeof(uint8_t)) {
  3180. SDPERR("Unexpected end of packet: continuation state data missing");
  3181. goto end;
  3182. }
  3183. cstate_len = *(uint8_t *) (pdata + rsp_count);
  3184. SDPDBG("Response id : %d", rsphdr->pdu_id);
  3185. SDPDBG("Attrlist byte count : %d", rsp_count);
  3186. SDPDBG("sdp_cstate_t length : %d", cstate_len);
  3187. /*
  3188. * a split response: concatenate intermediate responses
  3189. * and the last one (which has cstate_len == 0)
  3190. */
  3191. if (cstate_len > 0 || rsp_concat_buf.data_size != 0) {
  3192. uint8_t *targetPtr = NULL;
  3193. cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;
  3194. /* build concatenated response buffer */
  3195. rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
  3196. rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
  3197. targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
  3198. memcpy(targetPtr, pdata, rsp_count);
  3199. rsp_concat_buf.data_size += rsp_count;
  3200. }
  3201. } while (cstate);
  3202. if (attr_list_len > 0) {
  3203. int scanned = 0;
  3204. if (rsp_concat_buf.data_size != 0) {
  3205. pdata = rsp_concat_buf.data;
  3206. pdata_len = rsp_concat_buf.data_size;
  3207. }
  3208. rec = sdp_extract_pdu(pdata, pdata_len, &scanned);
  3209. }
  3210. end:
  3211. free(reqbuf);
  3212. free(rsp_concat_buf.data);
  3213. free(rspbuf);
  3214. return rec;
  3215. }
  3216. /*
  3217. * SDP transaction structure for asynchronous search
  3218. */
  3219. struct sdp_transaction {
  3220. sdp_callback_t *cb; /* called when the transaction finishes */
  3221. void *udata; /* client user data */
  3222. uint8_t *reqbuf; /* pointer to request PDU */
  3223. sdp_buf_t rsp_concat_buf;
  3224. uint32_t reqsize; /* without cstate */
  3225. int err; /* ZERO if success or the errno if failed */
  3226. };
  3227. /*
  3228. * Creates a new sdp session for asynchronous search
  3229. * INPUT:
  3230. * int sk
  3231. * non-blocking L2CAP socket
  3232. *
  3233. * RETURN:
  3234. * sdp_session_t *
  3235. * NULL - On memory allocation failure
  3236. */
  3237. sdp_session_t *sdp_create(int sk, uint32_t flags)
  3238. {
  3239. sdp_session_t *session;
  3240. struct sdp_transaction *t;
  3241. session = bt_malloc0(sizeof(sdp_session_t));
  3242. if (!session) {
  3243. errno = ENOMEM;
  3244. return NULL;
  3245. }
  3246. session->flags = flags;
  3247. session->sock = sk;
  3248. t = bt_malloc0(sizeof(struct sdp_transaction));
  3249. if (!t) {
  3250. errno = ENOMEM;
  3251. free(session);
  3252. return NULL;
  3253. }
  3254. session->priv = t;
  3255. return session;
  3256. }
  3257. /*
  3258. * Sets the callback function/user data used to notify the application
  3259. * that the asynchronous transaction finished. This function must be
  3260. * called before request an asynchronous search.
  3261. *
  3262. * INPUT:
  3263. * sdp_session_t *session
  3264. * Current sdp session to be handled
  3265. * sdp_callback_t *cb
  3266. * callback to be called when the transaction finishes
  3267. * void *udata
  3268. * user data passed to callback
  3269. * RETURN:
  3270. * 0 - Success
  3271. * -1 - Failure
  3272. */
  3273. int sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata)
  3274. {
  3275. struct sdp_transaction *t;
  3276. if (!session || !session->priv)
  3277. return -1;
  3278. t = session->priv;
  3279. t->cb = func;
  3280. t->udata = udata;
  3281. return 0;
  3282. }
  3283. /*
  3284. * This function starts an asynchronous service search request.
  3285. * The incoming and outgoing data are stored in the transaction structure
  3286. * buffers. When there is incoming data the sdp_process function must be
  3287. * called to get the data and handle the continuation state.
  3288. *
  3289. * INPUT :
  3290. * sdp_session_t *session
  3291. * Current sdp session to be handled
  3292. *
  3293. * sdp_list_t *search
  3294. * Singly linked list containing elements of the search
  3295. * pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16)
  3296. * of the service to be searched
  3297. *
  3298. * uint16_t max_rec_num
  3299. * A 16 bit integer which tells the service, the maximum
  3300. * entries that the client can handle in the response. The
  3301. * server is obliged not to return > max_rec_num entries
  3302. *
  3303. * OUTPUT :
  3304. *
  3305. * int return value
  3306. * 0 - if the request has been sent properly
  3307. * -1 - On any failure and sets errno
  3308. */
  3309. int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, uint16_t max_rec_num)
  3310. {
  3311. struct sdp_transaction *t;
  3312. sdp_pdu_hdr_t *reqhdr;
  3313. uint8_t *pdata;
  3314. int cstate_len, seqlen = 0;
  3315. if (!session || !session->priv)
  3316. return -1;
  3317. t = session->priv;
  3318. /* clean possible allocated buffer */
  3319. free(t->rsp_concat_buf.data);
  3320. memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
  3321. if (!t->reqbuf) {
  3322. t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
  3323. if (!t->reqbuf) {
  3324. t->err = ENOMEM;
  3325. goto end;
  3326. }
  3327. }
  3328. memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
  3329. reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
  3330. reqhdr->tid = htons(sdp_gen_tid(session));
  3331. reqhdr->pdu_id = SDP_SVC_SEARCH_REQ;
  3332. /* generate PDU */
  3333. pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
  3334. t->reqsize = sizeof(sdp_pdu_hdr_t);
  3335. /* add service class IDs for search */
  3336. seqlen = gen_searchseq_pdu(pdata, search);
  3337. if (seqlen < 0) {
  3338. t->err = EINVAL;
  3339. goto end;
  3340. }
  3341. SDPDBG("Data seq added : %d", seqlen);
  3342. /* now set the length and increment the pointer */
  3343. t->reqsize += seqlen;
  3344. pdata += seqlen;
  3345. bt_put_be16(max_rec_num, pdata);
  3346. t->reqsize += sizeof(uint16_t);
  3347. pdata += sizeof(uint16_t);
  3348. /* set the request header's param length */
  3349. cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
  3350. reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
  3351. if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
  3352. SDPERR("Error sending data:%m");
  3353. t->err = errno;
  3354. goto end;
  3355. }
  3356. return 0;
  3357. end:
  3358. free(t->reqbuf);
  3359. t->reqbuf = NULL;
  3360. return -1;
  3361. }
  3362. /*
  3363. * This function starts an asynchronous service attribute request.
  3364. * The incoming and outgoing data are stored in the transaction structure
  3365. * buffers. When there is incoming data the sdp_process function must be
  3366. * called to get the data and handle the continuation state.
  3367. *
  3368. * INPUT :
  3369. * sdp_session_t *session
  3370. * Current sdp session to be handled
  3371. *
  3372. * uint32_t handle
  3373. * The handle of the service for which the attribute(s) are
  3374. * requested
  3375. *
  3376. * sdp_attrreq_type_t reqtype
  3377. * Attribute identifiers are 16 bit unsigned integers specified
  3378. * in one of 2 ways described below :
  3379. * SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
  3380. * They are the actual attribute identifiers in ascending order
  3381. *
  3382. * SDP_ATTR_REQ_RANGE - 32bit identifier range
  3383. * The high-order 16bits is the start of range
  3384. * the low-order 16bits are the end of range
  3385. * 0x0000 to 0xFFFF gets all attributes
  3386. *
  3387. * sdp_list_t *attrid_list
  3388. * Singly linked list containing attribute identifiers desired.
  3389. * Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
  3390. * or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
  3391. *
  3392. * OUTPUT :
  3393. * int return value
  3394. * 0 - if the request has been sent properly
  3395. * -1 - On any failure and sets errno
  3396. */
  3397. int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list)
  3398. {
  3399. struct sdp_transaction *t;
  3400. sdp_pdu_hdr_t *reqhdr;
  3401. uint8_t *pdata;
  3402. int cstate_len, seqlen = 0;
  3403. if (!session || !session->priv)
  3404. return -1;
  3405. t = session->priv;
  3406. /* clean possible allocated buffer */
  3407. free(t->rsp_concat_buf.data);
  3408. memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
  3409. if (!t->reqbuf) {
  3410. t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
  3411. if (!t->reqbuf) {
  3412. t->err = ENOMEM;
  3413. goto end;
  3414. }
  3415. }
  3416. memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
  3417. reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
  3418. reqhdr->tid = htons(sdp_gen_tid(session));
  3419. reqhdr->pdu_id = SDP_SVC_ATTR_REQ;
  3420. /* generate PDU */
  3421. pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
  3422. t->reqsize = sizeof(sdp_pdu_hdr_t);
  3423. /* add the service record handle */
  3424. bt_put_be32(handle, pdata);
  3425. t->reqsize += sizeof(uint32_t);
  3426. pdata += sizeof(uint32_t);
  3427. /* specify the response limit */
  3428. bt_put_be16(65535, pdata);
  3429. t->reqsize += sizeof(uint16_t);
  3430. pdata += sizeof(uint16_t);
  3431. /* get attr seq PDU form */
  3432. seqlen = gen_attridseq_pdu(pdata, attrid_list,
  3433. reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32);
  3434. if (seqlen == -1) {
  3435. t->err = EINVAL;
  3436. goto end;
  3437. }
  3438. /* now set the length and increment the pointer */
  3439. t->reqsize += seqlen;
  3440. pdata += seqlen;
  3441. SDPDBG("Attr list length : %d", seqlen);
  3442. /* set the request header's param length */
  3443. cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
  3444. reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
  3445. if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
  3446. SDPERR("Error sending data:%m");
  3447. t->err = errno;
  3448. goto end;
  3449. }
  3450. return 0;
  3451. end:
  3452. free(t->reqbuf);
  3453. t->reqbuf = NULL;
  3454. return -1;
  3455. }
  3456. /*
  3457. * This function starts an asynchronous service search attributes.
  3458. * It is a service search request combined with attribute request. The incoming
  3459. * and outgoing data are stored in the transaction structure buffers. When there
  3460. * is incoming data the sdp_process function must be called to get the data
  3461. * and handle the continuation state.
  3462. *
  3463. * INPUT:
  3464. * sdp_session_t *session
  3465. * Current sdp session to be handled
  3466. *
  3467. * sdp_list_t *search
  3468. * Singly linked list containing elements of the search
  3469. * pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
  3470. * of the service to be searched
  3471. *
  3472. * AttributeSpecification attrSpec
  3473. * Attribute identifiers are 16 bit unsigned integers specified
  3474. * in one of 2 ways described below :
  3475. * SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
  3476. * They are the actual attribute identifiers in ascending order
  3477. *
  3478. * SDP_ATTR_REQ_RANGE - 32bit identifier range
  3479. * The high-order 16bits is the start of range
  3480. * the low-order 16bits are the end of range
  3481. * 0x0000 to 0xFFFF gets all attributes
  3482. *
  3483. * sdp_list_t *attrid_list
  3484. * Singly linked list containing attribute identifiers desired.
  3485. * Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
  3486. * or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
  3487. *
  3488. * RETURN:
  3489. * 0 - if the request has been sent properly
  3490. * -1 - On any failure
  3491. */
  3492. int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *search, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list)
  3493. {
  3494. struct sdp_transaction *t;
  3495. sdp_pdu_hdr_t *reqhdr;
  3496. uint8_t *pdata;
  3497. int cstate_len, seqlen = 0;
  3498. if (!session || !session->priv)
  3499. return -1;
  3500. t = session->priv;
  3501. /* clean possible allocated buffer */
  3502. free(t->rsp_concat_buf.data);
  3503. memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
  3504. if (!t->reqbuf) {
  3505. t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
  3506. if (!t->reqbuf) {
  3507. t->err = ENOMEM;
  3508. goto end;
  3509. }
  3510. }
  3511. memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
  3512. reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
  3513. reqhdr->tid = htons(sdp_gen_tid(session));
  3514. reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ;
  3515. /* generate PDU */
  3516. pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
  3517. t->reqsize = sizeof(sdp_pdu_hdr_t);
  3518. /* add service class IDs for search */
  3519. seqlen = gen_searchseq_pdu(pdata, search);
  3520. if (seqlen < 0) {
  3521. t->err = EINVAL;
  3522. goto end;
  3523. }
  3524. SDPDBG("Data seq added : %d", seqlen);
  3525. /* now set the length and increment the pointer */
  3526. t->reqsize += seqlen;
  3527. pdata += seqlen;
  3528. bt_put_be16(SDP_MAX_ATTR_LEN, pdata);
  3529. t->reqsize += sizeof(uint16_t);
  3530. pdata += sizeof(uint16_t);
  3531. SDPDBG("Max attr byte count : %d", SDP_MAX_ATTR_LEN);
  3532. /* get attr seq PDU form */
  3533. seqlen = gen_attridseq_pdu(pdata, attrid_list,
  3534. reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32);
  3535. if (seqlen == -1) {
  3536. t->err = EINVAL;
  3537. goto end;
  3538. }
  3539. pdata += seqlen;
  3540. SDPDBG("Attr list length : %d", seqlen);
  3541. t->reqsize += seqlen;
  3542. /* set the request header's param length */
  3543. cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
  3544. reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
  3545. if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
  3546. SDPERR("Error sending data:%m");
  3547. t->err = errno;
  3548. goto end;
  3549. }
  3550. return 0;
  3551. end:
  3552. free(t->reqbuf);
  3553. t->reqbuf = NULL;
  3554. return -1;
  3555. }
  3556. /*
  3557. * Function used to get the error reason after sdp_callback_t function has been called
  3558. * and the status is 0xffff or if sdp_service_{search, attr, search_attr}_async returns -1.
  3559. * It indicates that an error NOT related to SDP_ErrorResponse happened. Get errno directly
  3560. * is not safe because multiple transactions can be triggered.
  3561. * This function must be used with asynchronous sdp functions only.
  3562. *
  3563. * INPUT:
  3564. * sdp_session_t *session
  3565. * Current sdp session to be handled
  3566. * RETURN:
  3567. * 0 = No error in the current transaction
  3568. * -1 - if the session is invalid
  3569. * positive value - the errno value
  3570. *
  3571. */
  3572. int sdp_get_error(sdp_session_t *session)
  3573. {
  3574. struct sdp_transaction *t;
  3575. if (!session || !session->priv) {
  3576. SDPERR("Invalid session");
  3577. return -1;
  3578. }
  3579. t = session->priv;
  3580. return t->err;
  3581. }
  3582. /*
  3583. * Receive the incoming SDP PDU. This function must be called when there is data
  3584. * available to be read. On continuation state, the original request (with a new
  3585. * transaction ID) and the continuation state data will be appended in the initial PDU.
  3586. * If an error happens or the transaction finishes the callback function will be called.
  3587. *
  3588. * INPUT:
  3589. * sdp_session_t *session
  3590. * Current sdp session to be handled
  3591. * RETURN:
  3592. * 0 - if the transaction is on continuation state
  3593. * -1 - On any failure or the transaction finished
  3594. */
  3595. int sdp_process(sdp_session_t *session)
  3596. {
  3597. struct sdp_transaction *t;
  3598. sdp_pdu_hdr_t *reqhdr, *rsphdr;
  3599. sdp_cstate_t *pcstate;
  3600. uint8_t *pdata, *rspbuf, *targetPtr;
  3601. int rsp_count, err = -1;
  3602. size_t size = 0;
  3603. int n, plen;
  3604. uint16_t status = 0xffff;
  3605. uint8_t pdu_id = 0x00;
  3606. if (!session || !session->priv) {
  3607. SDPERR("Invalid session");
  3608. return -1;
  3609. }
  3610. rspbuf = bt_malloc0(SDP_RSP_BUFFER_SIZE);
  3611. if (!rspbuf) {
  3612. SDPERR("Response buffer alloc failure:%m (%d)", errno);
  3613. return -1;
  3614. }
  3615. t = session->priv;
  3616. reqhdr = (sdp_pdu_hdr_t *)t->reqbuf;
  3617. rsphdr = (sdp_pdu_hdr_t *)rspbuf;
  3618. pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
  3619. n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE);
  3620. if (n < 0) {
  3621. SDPERR("Read response:%m (%d)", errno);
  3622. t->err = errno;
  3623. goto end;
  3624. }
  3625. if (reqhdr->tid != rsphdr->tid) {
  3626. t->err = EPROTO;
  3627. SDPERR("Protocol error: transaction id does not match");
  3628. goto end;
  3629. }
  3630. if (n != (int) (ntohs(rsphdr->plen) + sizeof(sdp_pdu_hdr_t))) {
  3631. t->err = EPROTO;
  3632. SDPERR("Protocol error: invalid length");
  3633. goto end;
  3634. }
  3635. pdu_id = rsphdr->pdu_id;
  3636. switch (rsphdr->pdu_id) {
  3637. uint8_t *ssr_pdata;
  3638. uint16_t tsrc, csrc;
  3639. case SDP_SVC_SEARCH_RSP:
  3640. /*
  3641. * TSRC: Total Service Record Count (2 bytes)
  3642. * CSRC: Current Service Record Count (2 bytes)
  3643. */
  3644. ssr_pdata = pdata;
  3645. tsrc = bt_get_be16(ssr_pdata);
  3646. ssr_pdata += sizeof(uint16_t);
  3647. csrc = bt_get_be16(ssr_pdata);
  3648. /* csrc should never be larger than tsrc */
  3649. if (csrc > tsrc) {
  3650. t->err = EPROTO;
  3651. SDPERR("Protocol error: wrong current service record count value.");
  3652. goto end;
  3653. }
  3654. SDPDBG("Total svc count: %d", tsrc);
  3655. SDPDBG("Current svc count: %d", csrc);
  3656. /* parameter length without continuation state */
  3657. plen = sizeof(tsrc) + sizeof(csrc) + csrc * 4;
  3658. if (t->rsp_concat_buf.data_size == 0) {
  3659. /* first fragment */
  3660. rsp_count = sizeof(tsrc) + sizeof(csrc) + csrc * 4;
  3661. } else if (t->rsp_concat_buf.data_size >= sizeof(uint16_t) * 2) {
  3662. /* point to the first csrc */
  3663. uint8_t *pcsrc = t->rsp_concat_buf.data + 2;
  3664. uint16_t tcsrc, tcsrc2;
  3665. /* FIXME: update the interface later. csrc doesn't need be passed to clients */
  3666. pdata += sizeof(uint16_t); /* point to csrc */
  3667. /* the first csrc contains the sum of partial csrc responses */
  3668. memcpy(&tcsrc, pcsrc, sizeof(tcsrc));
  3669. memcpy(&tcsrc2, pdata, sizeof(tcsrc2));
  3670. tcsrc += tcsrc2;
  3671. memcpy(pcsrc, &tcsrc, sizeof(tcsrc));
  3672. pdata += sizeof(uint16_t); /* point to the first handle */
  3673. rsp_count = csrc * 4;
  3674. } else {
  3675. t->err = EPROTO;
  3676. SDPERR("Protocol error: invalid PDU size");
  3677. status = SDP_INVALID_PDU_SIZE;
  3678. goto end;
  3679. }
  3680. status = 0x0000;
  3681. break;
  3682. case SDP_SVC_ATTR_RSP:
  3683. case SDP_SVC_SEARCH_ATTR_RSP:
  3684. rsp_count = bt_get_be16(pdata);
  3685. SDPDBG("Attrlist byte count : %d", rsp_count);
  3686. /* Valid range for rsp_count is 0x0002-0xFFFF */
  3687. if (t->rsp_concat_buf.data_size == 0 && rsp_count < 0x0002) {
  3688. t->err = EPROTO;
  3689. SDPERR("Protocol error: invalid AttrList size");
  3690. status = SDP_INVALID_PDU_SIZE;
  3691. goto end;
  3692. }
  3693. /*
  3694. * Number of bytes in the AttributeLists parameter(without
  3695. * continuation state) + AttributeListsByteCount field size.
  3696. */
  3697. plen = sizeof(uint16_t) + rsp_count;
  3698. pdata += sizeof(uint16_t); /* points to attribute list */
  3699. status = 0x0000;
  3700. break;
  3701. case SDP_ERROR_RSP:
  3702. status = bt_get_be16(pdata);
  3703. size = ntohs(rsphdr->plen);
  3704. goto end;
  3705. default:
  3706. t->err = EPROTO;
  3707. SDPERR("Illegal PDU ID: 0x%x", rsphdr->pdu_id);
  3708. goto end;
  3709. }
  3710. /* Out of bound check before using rsp_count as offset for
  3711. * continuation state, which has at least a one byte size
  3712. * field.
  3713. */
  3714. if ((n - (int) sizeof(sdp_pdu_hdr_t)) < plen + 1) {
  3715. t->err = EPROTO;
  3716. SDPERR("Protocol error: invalid PDU size");
  3717. status = SDP_INVALID_PDU_SIZE;
  3718. goto end;
  3719. }
  3720. pcstate = (sdp_cstate_t *) (pdata + rsp_count);
  3721. SDPDBG("Cstate length : %d", pcstate->length);
  3722. /*
  3723. * Check out of bound. Continuation state must have at least
  3724. * 1 byte: ZERO to indicate that it is not a partial response.
  3725. */
  3726. if ((n - (int) sizeof(sdp_pdu_hdr_t)) != (plen + pcstate->length + 1)) {
  3727. t->err = EPROTO;
  3728. SDPERR("Protocol error: wrong PDU size.");
  3729. status = 0xffff;
  3730. goto end;
  3731. }
  3732. /*
  3733. * This is a split response, need to concatenate intermediate
  3734. * responses and the last one which will have cstate length == 0
  3735. */
  3736. t->rsp_concat_buf.data = realloc(t->rsp_concat_buf.data, t->rsp_concat_buf.data_size + rsp_count);
  3737. targetPtr = t->rsp_concat_buf.data + t->rsp_concat_buf.data_size;
  3738. t->rsp_concat_buf.buf_size = t->rsp_concat_buf.data_size + rsp_count;
  3739. memcpy(targetPtr, pdata, rsp_count);
  3740. t->rsp_concat_buf.data_size += rsp_count;
  3741. if (pcstate->length > 0) {
  3742. int reqsize, cstate_len;
  3743. reqhdr->tid = htons(sdp_gen_tid(session));
  3744. /* add continuation state */
  3745. cstate_len = copy_cstate(t->reqbuf + t->reqsize,
  3746. SDP_REQ_BUFFER_SIZE - t->reqsize, pcstate);
  3747. reqsize = t->reqsize + cstate_len;
  3748. /* set the request header's param length */
  3749. reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
  3750. if (sdp_send_req(session, t->reqbuf, reqsize) < 0) {
  3751. SDPERR("Error sending data:%m(%d)", errno);
  3752. status = 0xffff;
  3753. t->err = errno;
  3754. goto end;
  3755. }
  3756. err = 0;
  3757. }
  3758. end:
  3759. if (err) {
  3760. if (t->rsp_concat_buf.data_size != 0) {
  3761. pdata = t->rsp_concat_buf.data;
  3762. size = t->rsp_concat_buf.data_size;
  3763. }
  3764. if (t->cb)
  3765. t->cb(pdu_id, status, pdata, size, t->udata);
  3766. }
  3767. free(rspbuf);
  3768. return err;
  3769. }
  3770. /*
  3771. * This is a service search request combined with the service
  3772. * attribute request. First a service class match is done and
  3773. * for matching service, requested attributes are extracted
  3774. *
  3775. * INPUT :
  3776. *
  3777. * sdp_list_t *search
  3778. * Singly linked list containing elements of the search
  3779. * pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
  3780. * of the service to be searched
  3781. *
  3782. * AttributeSpecification attrSpec
  3783. * Attribute identifiers are 16 bit unsigned integers specified
  3784. * in one of 2 ways described below :
  3785. * SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
  3786. * They are the actual attribute identifiers in ascending order
  3787. *
  3788. * SDP_ATTR_REQ_RANGE - 32bit identifier range
  3789. * The high-order 16bits is the start of range
  3790. * the low-order 16bits are the end of range
  3791. * 0x0000 to 0xFFFF gets all attributes
  3792. *
  3793. * sdp_list_t *attrids
  3794. * Singly linked list containing attribute identifiers desired.
  3795. * Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
  3796. * or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
  3797. *
  3798. * OUTPUT :
  3799. * int return value
  3800. * 0:
  3801. * The request completed successfully. This does not
  3802. * mean the requested services were found
  3803. * -1:
  3804. * On any error and sets errno
  3805. *
  3806. * sdp_list_t **rsp
  3807. * This variable is set on a successful return to point to
  3808. * service(s) found. Each element of this list is of type
  3809. * sdp_record_t* (of the services which matched the search list)
  3810. */
  3811. int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search, sdp_attrreq_type_t reqtype, const sdp_list_t *attrids, sdp_list_t **rsp)
  3812. {
  3813. int status = 0;
  3814. uint32_t reqsize = 0, _reqsize;
  3815. uint32_t rspsize = 0;
  3816. int seqlen = 0, attr_list_len = 0;
  3817. int rsp_count = 0, cstate_len = 0;
  3818. unsigned int pdata_len;
  3819. uint8_t *pdata, *_pdata;
  3820. uint8_t *reqbuf, *rspbuf;
  3821. sdp_pdu_hdr_t *reqhdr, *rsphdr;
  3822. uint8_t dataType;
  3823. sdp_list_t *rec_list = NULL;
  3824. sdp_buf_t rsp_concat_buf;
  3825. sdp_cstate_t *cstate = NULL;
  3826. if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) {
  3827. errno = EINVAL;
  3828. return -1;
  3829. }
  3830. memset(&rsp_concat_buf, 0, sizeof(sdp_buf_t));
  3831. reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
  3832. rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
  3833. if (!reqbuf || !rspbuf) {
  3834. errno = ENOMEM;
  3835. status = -1;
  3836. goto end;
  3837. }
  3838. reqhdr = (sdp_pdu_hdr_t *) reqbuf;
  3839. reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ;
  3840. /* generate PDU */
  3841. pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
  3842. reqsize = sizeof(sdp_pdu_hdr_t);
  3843. /* add service class IDs for search */
  3844. seqlen = gen_searchseq_pdu(pdata, search);
  3845. if (seqlen < 0) {
  3846. errno = EINVAL;
  3847. status = -1;
  3848. goto end;
  3849. }
  3850. SDPDBG("Data seq added : %d", seqlen);
  3851. /* now set the length and increment the pointer */
  3852. reqsize += seqlen;
  3853. pdata += seqlen;
  3854. bt_put_be16(SDP_MAX_ATTR_LEN, pdata);
  3855. reqsize += sizeof(uint16_t);
  3856. pdata += sizeof(uint16_t);
  3857. SDPDBG("Max attr byte count : %d", SDP_MAX_ATTR_LEN);
  3858. /* get attr seq PDU form */
  3859. seqlen = gen_attridseq_pdu(pdata, attrids,
  3860. reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32);
  3861. if (seqlen == -1) {
  3862. errno = EINVAL;
  3863. status = -1;
  3864. goto end;
  3865. }
  3866. pdata += seqlen;
  3867. SDPDBG("Attr list length : %d", seqlen);
  3868. reqsize += seqlen;
  3869. *rsp = 0;
  3870. /* save before Continuation State */
  3871. _pdata = pdata;
  3872. _reqsize = reqsize;
  3873. do {
  3874. reqhdr->tid = htons(sdp_gen_tid(session));
  3875. /* add continuation state (can be null) */
  3876. reqsize = _reqsize + copy_cstate(_pdata,
  3877. SDP_REQ_BUFFER_SIZE - _reqsize, cstate);
  3878. /* set the request header's param length */
  3879. reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
  3880. rsphdr = (sdp_pdu_hdr_t *) rspbuf;
  3881. status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
  3882. if (rspsize < sizeof(sdp_pdu_hdr_t)) {
  3883. SDPERR("Unexpected end of packet");
  3884. status = -1;
  3885. goto end;
  3886. }
  3887. if (status < 0) {
  3888. SDPDBG("Status : 0x%x", rsphdr->pdu_id);
  3889. goto end;
  3890. }
  3891. if (rsphdr->pdu_id == SDP_ERROR_RSP) {
  3892. status = -1;
  3893. goto end;
  3894. }
  3895. pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
  3896. pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);
  3897. if (pdata_len < sizeof(uint16_t)) {
  3898. SDPERR("Unexpected end of packet");
  3899. status = -1;
  3900. goto end;
  3901. }
  3902. rsp_count = bt_get_be16(pdata);
  3903. attr_list_len += rsp_count;
  3904. pdata += sizeof(uint16_t); /* pdata points to attribute list */
  3905. pdata_len -= sizeof(uint16_t);
  3906. if (pdata_len < rsp_count + sizeof(uint8_t)) {
  3907. SDPERR("Unexpected end of packet: continuation state data missing");
  3908. status = -1;
  3909. goto end;
  3910. }
  3911. cstate_len = *(uint8_t *) (pdata + rsp_count);
  3912. SDPDBG("Attrlist byte count : %d", attr_list_len);
  3913. SDPDBG("Response byte count : %d", rsp_count);
  3914. SDPDBG("Cstate length : %d", cstate_len);
  3915. /*
  3916. * This is a split response, need to concatenate intermediate
  3917. * responses and the last one which will have cstate_len == 0
  3918. */
  3919. if (cstate_len > 0 || rsp_concat_buf.data_size != 0) {
  3920. uint8_t *targetPtr = NULL;
  3921. cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;
  3922. /* build concatenated response buffer */
  3923. rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
  3924. targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
  3925. rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
  3926. memcpy(targetPtr, pdata, rsp_count);
  3927. rsp_concat_buf.data_size += rsp_count;
  3928. }
  3929. } while (cstate);
  3930. if (attr_list_len > 0) {
  3931. int scanned = 0;
  3932. if (rsp_concat_buf.data_size != 0) {
  3933. pdata = rsp_concat_buf.data;
  3934. pdata_len = rsp_concat_buf.data_size;
  3935. }
  3936. /*
  3937. * Response is a sequence of sequence(s) for one or
  3938. * more data element sequence(s) representing services
  3939. * for which attributes are returned
  3940. */
  3941. scanned = sdp_extract_seqtype(pdata, pdata_len, &dataType, &seqlen);
  3942. SDPDBG("Bytes scanned : %d", scanned);
  3943. SDPDBG("Seq length : %d", seqlen);
  3944. if (scanned && seqlen) {
  3945. pdata += scanned;
  3946. pdata_len -= scanned;
  3947. do {
  3948. int recsize = 0;
  3949. sdp_record_t *rec = sdp_extract_pdu(pdata, pdata_len, &recsize);
  3950. if (rec == NULL) {
  3951. SDPERR("SVC REC is null");
  3952. status = -1;
  3953. goto end;
  3954. }
  3955. if (!recsize) {
  3956. sdp_record_free(rec);
  3957. break;
  3958. }
  3959. scanned += recsize;
  3960. pdata += recsize;
  3961. pdata_len -= recsize;
  3962. SDPDBG("Loc seq length : %d", recsize);
  3963. SDPDBG("Svc Rec Handle : 0x%x", rec->handle);
  3964. SDPDBG("Bytes scanned : %d", scanned);
  3965. SDPDBG("Attrlist byte count : %d", attr_list_len);
  3966. rec_list = sdp_list_append(rec_list, rec);
  3967. } while (scanned < attr_list_len && pdata_len > 0);
  3968. SDPDBG("Successful scan of service attr lists");
  3969. *rsp = rec_list;
  3970. }
  3971. }
  3972. end:
  3973. free(rsp_concat_buf.data);
  3974. free(reqbuf);
  3975. free(rspbuf);
  3976. return status;
  3977. }
  3978. /*
  3979. * Find devices in the piconet.
  3980. */
  3981. int sdp_general_inquiry(inquiry_info *ii, int num_dev, int duration, uint8_t *found)
  3982. {
  3983. int n = hci_inquiry(-1, 10, num_dev, NULL, &ii, 0);
  3984. if (n < 0) {
  3985. SDPERR("Inquiry failed:%m");
  3986. return -1;
  3987. }
  3988. *found = n;
  3989. return 0;
  3990. }
  3991. int sdp_close(sdp_session_t *session)
  3992. {
  3993. struct sdp_transaction *t;
  3994. int ret;
  3995. if (!session)
  3996. return -1;
  3997. ret = close(session->sock);
  3998. t = session->priv;
  3999. if (t) {
  4000. free(t->reqbuf);
  4001. free(t->rsp_concat_buf.data);
  4002. free(t);
  4003. }
  4004. free(session);
  4005. return ret;
  4006. }
  4007. static inline int sdp_is_local(const bdaddr_t *device)
  4008. {
  4009. return memcmp(device, BDADDR_LOCAL, sizeof(bdaddr_t)) == 0;
  4010. }
  4011. static int sdp_connect_local(sdp_session_t *session)
  4012. {
  4013. struct sockaddr_un sa;
  4014. session->sock = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
  4015. if (session->sock < 0)
  4016. return -1;
  4017. session->local = 1;
  4018. sa.sun_family = AF_UNIX;
  4019. strcpy(sa.sun_path, SDP_UNIX_PATH);
  4020. return connect(session->sock, (struct sockaddr *) &sa, sizeof(sa));
  4021. }
  4022. static int set_l2cap_mtu(int sk, uint16_t mtu)
  4023. {
  4024. struct l2cap_options l2o;
  4025. socklen_t len;
  4026. memset(&l2o, 0, sizeof(l2o));
  4027. len = sizeof(l2o);
  4028. if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &len) < 0)
  4029. return -1;
  4030. l2o.imtu = mtu;
  4031. l2o.omtu = mtu;
  4032. if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)) < 0)
  4033. return -1;
  4034. return 0;
  4035. }
  4036. static int sdp_connect_l2cap(const bdaddr_t *src,
  4037. const bdaddr_t *dst, sdp_session_t *session)
  4038. {
  4039. uint32_t flags = session->flags;
  4040. struct sockaddr_l2 sa;
  4041. int sk;
  4042. int sockflags = SOCK_SEQPACKET | SOCK_CLOEXEC;
  4043. if (flags & SDP_NON_BLOCKING)
  4044. sockflags |= SOCK_NONBLOCK;
  4045. session->sock = socket(PF_BLUETOOTH, sockflags, BTPROTO_L2CAP);
  4046. if (session->sock < 0)
  4047. return -1;
  4048. session->local = 0;
  4049. sk = session->sock;
  4050. memset(&sa, 0, sizeof(sa));
  4051. sa.l2_family = AF_BLUETOOTH;
  4052. sa.l2_psm = 0;
  4053. if (bacmp(src, BDADDR_ANY)) {
  4054. sa.l2_bdaddr = *src;
  4055. if (bind(sk, (struct sockaddr *) &sa, sizeof(sa)) < 0)
  4056. return -1;
  4057. }
  4058. if (flags & SDP_WAIT_ON_CLOSE) {
  4059. struct linger l = { .l_onoff = 1, .l_linger = 1 };
  4060. if (setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0)
  4061. return -1;
  4062. }
  4063. if ((flags & SDP_LARGE_MTU) &&
  4064. set_l2cap_mtu(sk, SDP_LARGE_L2CAP_MTU) < 0)
  4065. return -1;
  4066. sa.l2_psm = htobs(SDP_PSM);
  4067. sa.l2_bdaddr = *dst;
  4068. do {
  4069. int ret = connect(sk, (struct sockaddr *) &sa, sizeof(sa));
  4070. if (!ret)
  4071. return 0;
  4072. if (ret < 0 && (flags & SDP_NON_BLOCKING) &&
  4073. (errno == EAGAIN || errno == EINPROGRESS))
  4074. return 0;
  4075. } while (errno == EBUSY && (flags & SDP_RETRY_IF_BUSY));
  4076. return -1;
  4077. }
  4078. sdp_session_t *sdp_connect(const bdaddr_t *src,
  4079. const bdaddr_t *dst, uint32_t flags)
  4080. {
  4081. sdp_session_t *session;
  4082. int err;
  4083. if ((flags & SDP_RETRY_IF_BUSY) && (flags & SDP_NON_BLOCKING)) {
  4084. errno = EINVAL;
  4085. return NULL;
  4086. }
  4087. session = sdp_create(-1, flags);
  4088. if (!session)
  4089. return NULL;
  4090. if (sdp_is_local(dst)) {
  4091. if (sdp_connect_local(session) < 0)
  4092. goto fail;
  4093. } else {
  4094. if (sdp_connect_l2cap(src, dst, session) < 0)
  4095. goto fail;
  4096. }
  4097. return session;
  4098. fail:
  4099. err = errno;
  4100. if (session->sock >= 0)
  4101. close(session->sock);
  4102. free(session->priv);
  4103. free(session);
  4104. errno = err;
  4105. return NULL;
  4106. }
  4107. int sdp_get_socket(const sdp_session_t *session)
  4108. {
  4109. return session->sock;
  4110. }
  4111. uint16_t sdp_gen_tid(sdp_session_t *session)
  4112. {
  4113. return session->tid++;
  4114. }
  4115. /*
  4116. * Set the supported features
  4117. */
  4118. int sdp_set_supp_feat(sdp_record_t *rec, const sdp_list_t *sf)
  4119. {
  4120. const sdp_list_t *p, *r;
  4121. sdp_data_t *feat, *seq_feat;
  4122. int seqlen, i;
  4123. void **seqDTDs, **seqVals;
  4124. seqlen = sdp_list_len(sf);
  4125. seqDTDs = malloc(seqlen * sizeof(void *));
  4126. if (!seqDTDs)
  4127. return -1;
  4128. seqVals = malloc(seqlen * sizeof(void *));
  4129. if (!seqVals) {
  4130. free(seqDTDs);
  4131. return -1;
  4132. }
  4133. for (p = sf, i = 0; p; p = p->next, i++) {
  4134. int plen, j;
  4135. void **dtds, **vals;
  4136. int *lengths;
  4137. plen = sdp_list_len(p->data);
  4138. dtds = malloc(plen * sizeof(void *));
  4139. if (!dtds)
  4140. goto fail;
  4141. vals = malloc(plen * sizeof(void *));
  4142. if (!vals) {
  4143. free(dtds);
  4144. goto fail;
  4145. }
  4146. lengths = malloc(plen * sizeof(int));
  4147. if (!lengths) {
  4148. free(dtds);
  4149. free(vals);
  4150. goto fail;
  4151. }
  4152. for (r = p->data, j = 0; r; r = r->next, j++) {
  4153. sdp_data_t *data = (sdp_data_t *) r->data;
  4154. dtds[j] = &data->dtd;
  4155. switch (data->dtd) {
  4156. case SDP_URL_STR8:
  4157. case SDP_URL_STR16:
  4158. case SDP_TEXT_STR8:
  4159. case SDP_TEXT_STR16:
  4160. vals[j] = data->val.str;
  4161. lengths[j] = data->unitSize - sizeof(uint8_t);
  4162. break;
  4163. case SDP_ALT8:
  4164. case SDP_ALT16:
  4165. case SDP_ALT32:
  4166. case SDP_SEQ8:
  4167. case SDP_SEQ16:
  4168. case SDP_SEQ32:
  4169. vals[j] = data->val.dataseq;
  4170. lengths[j] = 0;
  4171. break;
  4172. default:
  4173. vals[j] = &data->val;
  4174. lengths[j] = 0;
  4175. break;
  4176. }
  4177. }
  4178. feat = sdp_seq_alloc_with_length(dtds, vals, lengths, plen);
  4179. free(dtds);
  4180. free(vals);
  4181. free(lengths);
  4182. if (!feat)
  4183. goto fail;
  4184. seqDTDs[i] = &feat->dtd;
  4185. seqVals[i] = feat;
  4186. }
  4187. seq_feat = sdp_seq_alloc(seqDTDs, seqVals, seqlen);
  4188. if (!seq_feat)
  4189. goto fail;
  4190. sdp_attr_replace(rec, SDP_ATTR_SUPPORTED_FEATURES_LIST, seq_feat);
  4191. free(seqVals);
  4192. free(seqDTDs);
  4193. return 0;
  4194. fail:
  4195. free(seqVals);
  4196. free(seqDTDs);
  4197. return -1;
  4198. }
  4199. /*
  4200. * Get the supported features
  4201. * If an error occurred -1 is returned and errno is set
  4202. */
  4203. int sdp_get_supp_feat(const sdp_record_t *rec, sdp_list_t **seqp)
  4204. {
  4205. sdp_data_t *sdpdata, *d;
  4206. sdp_list_t *tseq;
  4207. tseq = NULL;
  4208. sdpdata = sdp_data_get(rec, SDP_ATTR_SUPPORTED_FEATURES_LIST);
  4209. if (!sdpdata || !SDP_IS_SEQ(sdpdata->dtd))
  4210. return sdp_get_uuidseq_attr(rec,
  4211. SDP_ATTR_SUPPORTED_FEATURES_LIST, seqp);
  4212. for (d = sdpdata->val.dataseq; d; d = d->next) {
  4213. sdp_data_t *dd;
  4214. sdp_list_t *subseq;
  4215. if (!SDP_IS_SEQ(d->dtd))
  4216. goto fail;
  4217. subseq = NULL;
  4218. for (dd = d->val.dataseq; dd; dd = dd->next) {
  4219. sdp_data_t *data;
  4220. void *val;
  4221. int length;
  4222. switch (dd->dtd) {
  4223. case SDP_URL_STR8:
  4224. case SDP_URL_STR16:
  4225. case SDP_TEXT_STR8:
  4226. case SDP_TEXT_STR16:
  4227. val = dd->val.str;
  4228. length = dd->unitSize - sizeof(uint8_t);
  4229. break;
  4230. case SDP_UINT8:
  4231. case SDP_UINT16:
  4232. val = &dd->val;
  4233. length = 0;
  4234. break;
  4235. default:
  4236. sdp_list_free(subseq, free);
  4237. goto fail;
  4238. }
  4239. data = sdp_data_alloc_with_length(dd->dtd, val, length);
  4240. if (data)
  4241. subseq = sdp_list_append(subseq, data);
  4242. }
  4243. tseq = sdp_list_append(tseq, subseq);
  4244. }
  4245. *seqp = tseq;
  4246. return 0;
  4247. fail:
  4248. while (tseq) {
  4249. sdp_list_t * next;
  4250. next = tseq->next;
  4251. sdp_list_free(tseq, free);
  4252. tseq = next;
  4253. }
  4254. errno = EINVAL;
  4255. return -1;
  4256. }
  4257. void sdp_add_lang_attr(sdp_record_t *rec)
  4258. {
  4259. sdp_lang_attr_t base_lang;
  4260. sdp_list_t *langs;
  4261. base_lang.code_ISO639 = (0x65 << 8) | 0x6e;
  4262. base_lang.encoding = 106;
  4263. base_lang.base_offset = SDP_PRIMARY_LANG_BASE;
  4264. langs = sdp_list_append(0, &base_lang);
  4265. sdp_set_lang_attr(rec, langs);
  4266. sdp_list_free(langs, NULL);
  4267. }